cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2509回复:18

请教一个指针的问题。

楼主#
更多 发布于:2005-07-18 23:10
  请教一个指针的问题。
这是在动态链接库DLL中的一个函数:

char *ReturnIntPointer(char *n)
{
       char *array;
      
       array =(char *) malloc(10);

       array[0] = 0;
       array[1] = 1;
       array[2] = 2;
       array[3] = 3;
       array[4] = 4;
       array[5] = 5;
       array[6] = 6;
       array[7] = 7;
       array[8] = 8;
       array[9] = 9;

       n=array;  //我想把指针n实际上当作一个返回参数来使用,可以吗?

       return array;
      
       }

  n=array;  //我想把指针n实际上当作一个返回参数来使用,可以吗?


int main()
{
       int *f,*m;
       char *n;
       int i,j;
       typedef char *(p1)(char *n);   //然后我在应用程序里这样定义,显式调用
       HINSTANCE gSample=LoadLibrary("mytest.dll");

       p1 *pReturnIntPointer = (p1*)GetProcAddress
                                                        (gSample,"ReturnIntPointer");

                (*pReturnIntPointer)(char *n);   //这样调用是错误的,我不知道该怎么办
                                             各位请指教一下,我怎么样才能正确的调用?

最新喜欢:

wzbhbbwzbhbb
mingfa
驱动牛犊
驱动牛犊
  • 注册日期2002-11-15
  • 最后登录2008-11-03
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-07-18 23:53
试试
pReturnIntPointer(char *n);  

这应是正确的调用
maqian
驱动中牛
驱动中牛
  • 注册日期2002-08-07
  • 最后登录2014-09-16
  • 粉丝2
  • 关注1
  • 积分12分
  • 威望120点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-07-19 12:12
楼主麻烦大了.
1、char *ReturnIntPointer(char **n)
2、*n=array;
3、typedef char *(*p1)(char **n);
4、(*pReturnIntPointer)(&n);
5、上面四条都是小问题,关键是返回指针的释放。你必须在dll中增加一个函数,来释放n所指向的内存。
五花马,千金裘,呼儿将出换美酒。 我不喝酒,喝可乐。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-07-19 20:24
两位的方法都试了,都不行。
1楼的调用语法格式好像就是错误的。
2楼的编译错误如下:
C:\mytest\app\app.cpp(39) : error C2664: 'char *(char *)' : cannot convert parameter 1 from 'char ** ' to 'char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

app.exe - 1 error(s), 0 warning(s)

实在是没辙了。我的VC基础较差,还请再指点一下。
xx_focus
驱动中牛
驱动中牛
  • 注册日期2003-08-06
  • 最后登录2007-06-08
  • 粉丝0
  • 关注0
  • 积分96分
  • 威望10点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-07-19 22:04
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”

void GetMemory(char **p, int num)
{
       *p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
       char *str = NULL;
       GetMemory2(&str, 100);       // 注意参数是 &str,而不是str
       strcpy(str, "hello");      
       cout<< str << endl;
       free(str);      
}
maqian
驱动中牛
驱动中牛
  • 注册日期2002-08-07
  • 最后登录2014-09-16
  • 粉丝2
  • 关注1
  • 积分12分
  • 威望120点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-07-20 10:02
楼主,仔细看我的第三条.
其实我本不想回这个贴子,因为1234这四条你自己看书或查MSDN都能找到.可是如果你只是简单地抄xx_focus网友的代码,因为你的函数在DLL中,那你的程序将出现问题.相比之下,第5条有一定难度,因此回了这个贴子.
五花马,千金裘,呼儿将出换美酒。 我不喝酒,喝可乐。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-07-21 22:00
多谢maqian了,不过我确实试了你说的方法,还是不行,我怀疑是不是我的VC有问题了,因为以前曾经遇到过中毒后VC出错的现象。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-07-21 23:20
也要感谢xx_focus兄!
maqian
驱动中牛
驱动中牛
  • 注册日期2002-08-07
  • 最后登录2014-09-16
  • 粉丝2
  • 关注1
  • 积分12分
  • 威望120点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-07-23 21:15
不好意思,第1条应该改为:
extern "C" __declspec ( dllexport )char *ReturnIntPointer(char **n)
DLL中应这样写:

extern "C" __declspec ( dllexport )char *ReturnIntPointer(char **n)
{
    ......
    *n=array;
     return array;
}

extern "C" __declspec ( dllexport ) void DllFree(void* p)
{
    free(p);
}


exe中这样写:
int main()
{
     int *f,*m;
     char *n;
     int i,j;
     typedef char *(*p1)(char **n);   //然后我在应用程序里这样定义,显式调用
     HINSTANCE gSample=LoadLibrary("mytest.dll");

     if( gSample == NULL )
    {
        return 0;
    }


     p1 pReturnIntPointer = (p1)GetProcAddress
                                    (gSample,"ReturnIntPointer");
    // 对照原代码,注意上面的更改

    if( pReturnIntPointer == NULL )
    {
        return 0;
    }
    (pReturnIntPointer)(&n);
    DllFree(n);
    FreeLibrary( gSample );
    return 1;
}

你代码问题太多,我原来没仔细看,漏掉了上面新提到的几处.不过再强调一次,其他问题都很简单,如果你能理解第5条,那说明你的水平有了很大提高了.
五花马,千金裘,呼儿将出换美酒。 我不喝酒,喝可乐。
caesun
驱动小牛
驱动小牛
  • 注册日期2001-12-10
  • 最后登录2006-12-01
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值393点
  • 好评度21点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-07-30 12:25
有个不明白的地方想请教一下maqian网友,
>>因为你的函数在DLL中,那你的程序将出现问题.相比之下,第5条有一定难度,因此回了这个贴子.

这是为什么?
在DLL里面malloc一块内存,在程序里直接free不行吗?
caesun
驱动小牛
驱动小牛
  • 注册日期2001-12-10
  • 最后登录2006-12-01
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值393点
  • 好评度21点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-07-30 12:29
另外回楼主

定义函数指针类型一般可以直接定义成
typedef char *(*PFN)(char *n);

这样直接用
PFN  pReturnIntPointer=(PFN)GetProcAddress....
maqian
驱动中牛
驱动中牛
  • 注册日期2002-08-07
  • 最后登录2014-09-16
  • 粉丝2
  • 关注1
  • 积分12分
  • 威望120点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-07-31 21:38
多谢楼上又找出一个错误。
“在DLL里面malloc一块内存,在程序里直接free不行吗”
这个和CRT的具体代码有关,会引起内存访问异常。
五花马,千金裘,呼儿将出换美酒。 我不喝酒,喝可乐。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-08-01 10:26
最近没上网,感谢各位!经过大家指点,这个试验终于成功了。
现在把这个简单的试验代码发出来,希望对其他的初学者有用。

mytest.cpp  --DLL文件

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <setupapi.h>

#include <stdlib.h>
#include <winioctl.h>
#include <iostream.h>

extern "C" _declspec(dllexport) char *ReturnIntPointer(char **n);
extern "C" _declspec(dllexport) void DllFree(void* p);

BOOL WINAPI DllMain (HANDLE hDLL, DWORD dwReason,LPVOID lpReserved)
{
       return TRUE;
}

_declspec(dllexport) char *ReturnIntPointer(char **n)  //此处不需要再用extern "C"
{
     char *array;
    
     array =(char *) malloc(10);

     array[0] = 0;
     array[1] = 1;
     array[2] = 2;
     array[3] = 3;
     array[4] = 4;
     array[5] = 5;
     array[6] = 6;
     array[7] = 7;
     array[8] = 8;
     array[9] = 9;

     *n=array; //想把指针n实际上当作一个返回参数来使用

     return array;
    
}

extern "C" __declspec ( dllexport ) void DllFree(void* p)
{
  free(p);
}



testdll.cpp  --应用程序

#include "stdafx.h"

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

#include <winioctl.h>
#include <iostream.h>

#include <winioctl.h>

int main()
{
       int i;
       char *n;
       typedef char (*p1)(char **n);   //显式调用

       HINSTANCE gSample=LoadLibrary("mytest.dll");

       if( gSample == NULL )
       {
              return 0;
       }

       p1 pReturnIntPointer = (p1)GetProcAddress(gSample,"ReturnIntPointer");

       if( pReturnIntPointer == NULL )
       {
              return 0;
       }

       (pReturnIntPointer)(&n);
      
       for(i=0;i<10;i++)
       {
              printf("data=%d \n",*n++);
       };

//       DllFree(n);   // maqian兄的关于内存释放的试验没做
      
       FreeLibrary( gSample );
      
       return 0;
}
maqian
驱动中牛
驱动中牛
  • 注册日期2002-08-07
  • 最后登录2014-09-16
  • 粉丝2
  • 关注1
  • 积分12分
  • 威望120点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-08-01 11:32
说话比较直,希望楼主别见怪.
你的代码不见得对其他初学者有多大用处.要实现这样的功能,在很多书上能找到更标准的代码.
就不说你加了很多用不上的include语句;"typedef char (*p1)(char **n); "少了个*号,这些并不影响程序运行.关键是你没有释放分配的内存,会造成内存泄露,可以说这段代码是有问题的.顺便说一句,内存泄露是JAVA阵营攻击C++阵营最大的话题之一.
五花马,千金裘,呼儿将出换美酒。 我不喝酒,喝可乐。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-08-01 11:50
谢谢maqian兄的指正!因为我是做硬件的,但是要用到这个功能,所以是现学现用的,没花太多时间钻研。不知道内存泄露对程序的执行会有什么影响吗?例如运行速度上。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
15楼#
发布于:2005-08-01 16:35
memo leak 会导致 你的机器运行越来越慢(可用内存慢慢变少) 如果运行时间长的程序,会导致最后当机。

对于c/c++程序员来说memo leak是最常见的错误,也是最不好debug的,要养成好习惯,用了就放掉。 否则在复杂的项目中你会找不到memo leak的地方。

对于复杂的项目,可以用boundschecker之类工具检查。不过不要太依赖工具,好的习惯比工具很强大。
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-08-01 19:21
原来如此,又长知识了,看来还是得花时间了解一些。
cover_me
驱动牛犊
驱动牛犊
  • 注册日期2004-04-25
  • 最后登录2006-04-29
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2005-08-11 09:39
今天想试试释放内存的试验。但奇怪的是运行的时候总是报错:“0X00000000指令引用的0X0000000内存。该内存不能为“READ”。”
是不是pDLLFree(n)里的n已经改变了?很纳闷,不知道哪里出错了?

pReturnIntPointer(&n);

for(i=0;i<10;i++)
{
      printf("data=%d \n",*n++);
};

pDLLFree(n);
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
18楼#
发布于:2005-08-11 11:55
下面是引用cover_me于2005-08-11 09:39发表的:
今天想试试释放内存的试验。但奇怪的是运行的时候总是报错:“0X00000000指令引用的0X0000000内存。该内存不能为“READ”。”
是不是pDLLFree(n)里的n已经改变了?很纳闷,不知道哪里出错了?

pReturnIntPointer(&n);

.......

你看看pDLLFree是不是为NULL
游客

返回顶部