当前位置: 技术问答>linux和unix
VS中调用c在cygwin生成的dll,出现了调用崩溃
来源: 互联网 发布时间:2017-05-30
本文导语: 大家好,我现在有个问题,苦苦折腾了几天,还没解决,因此上来寻找知道问题的高手,先感谢所有进入看帖的人,下面进入正文: 我现在有个需求,需要将linux下的c程序作成dll,提供给windows平台的vs程序调用,代...
大家好,我现在有个问题,苦苦折腾了几天,还没解决,因此上来寻找知道问题的高手,先感谢所有进入看帖的人,下面进入正文:
我现在有个需求,需要将linux下的c程序作成dll,提供给windows平台的vs程序调用,代码实现跨平台。
一、采用的方式是:通过cygwin把c代码生成dll文件,然后在vs2005中动态载入dll,调用接口函数,具体做法如下:
1、cygwin中生成dll:
1) gcc -c mytest.c
2) gcc -shared -o mytest.dll mytest.o
2、mytest.dll和cygwin1.dll放到vs2005工程目录。
3、vs2005中调用(工程为MFC对话框工程):
1) 导入cygwin1.dll,初始化:
// code1:
//文件头部定义代码:
HMODULE h;
typedef int(*PFN_CYGWIN_INIT)();
// 工程入口载入cygwin1.dll
h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_INIT init = (PFN_CYGWIN_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
2) 在工程需要的地方调用dll的方法,代码如下(FreeLibrary没写出来):
// code2:
//文件头部定义代码:
HMODULE hLib;
typedef int(*PFN_TIME)(int a, int b);
PFN_TIME getTime;
// 某个方法内调用
hLib = LoadLibrary(TEXT("mytest.dll"));
getTime = (PFN_TIME)GetProcAddress(h, "Add_func");
long t = getTime(3, 5);
二、出现的问题:
1、code2紧跟在code1后面,程序正常调用,没有问题,code2放在工程中别的位置,有的地方可以,有的地方不行(貌似越靠程序流程前面,调用就会正常)。
2、现象:出问题的时候,有两种现象,他们是我把调用代码放在不同的地方出现的:一种是dll能正常调用,但发现在LoadLibrary之后,当前类的指针this就变成了0x00000000,退出当前函数,程序就崩溃;另一种情况是调试的时候,跟到long t = getTime(3, 5);这一行,程序就没有了反应,好像在里面出不来了,没往下执行了。
三、尝试过的方法:
1、官方说“Make sure you have 4K of scratch space at the bottom of your stack”,所以我在vs中也做了设置:“项目”属性->配置属性->链接器->系统,堆栈保留大小和堆栈提交大小设成了2097152和4096,对应十六进制100000,1000,这个值是经dumpbin /HEADERS mytest.dll查到的。
2、也试过在编译dll的时候在gcc中设置了上面的值,但也无济于事。
猜测:
1、“4K of scratch space”很可能是一个原因,但是不太清楚是否是这样设置;
2、会否是因为对话框程序在切换对话框后另启了一个线程,导致无法读到原来堆栈的bottom信息;
3、编译dll的时候是否还有别的option要加,因为奇怪的是:如果我的dll里面是一个简单的加法运算的方法,程序调用是完全没有问题的!但是我的dll源文件里面加入了用来做一个获取当前时间的方法,程序调用就出现了本文的问题。
希望在这里有缘碰到刚好在这方面有经验的朋友给予赐教,感谢你花时间看我的问题!
我现在有个需求,需要将linux下的c程序作成dll,提供给windows平台的vs程序调用,代码实现跨平台。
一、采用的方式是:通过cygwin把c代码生成dll文件,然后在vs2005中动态载入dll,调用接口函数,具体做法如下:
1、cygwin中生成dll:
1) gcc -c mytest.c
2) gcc -shared -o mytest.dll mytest.o
2、mytest.dll和cygwin1.dll放到vs2005工程目录。
3、vs2005中调用(工程为MFC对话框工程):
1) 导入cygwin1.dll,初始化:
// code1:
//文件头部定义代码:
HMODULE h;
typedef int(*PFN_CYGWIN_INIT)();
// 工程入口载入cygwin1.dll
h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_INIT init = (PFN_CYGWIN_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
2) 在工程需要的地方调用dll的方法,代码如下(FreeLibrary没写出来):
// code2:
//文件头部定义代码:
HMODULE hLib;
typedef int(*PFN_TIME)(int a, int b);
PFN_TIME getTime;
// 某个方法内调用
hLib = LoadLibrary(TEXT("mytest.dll"));
getTime = (PFN_TIME)GetProcAddress(h, "Add_func");
long t = getTime(3, 5);
二、出现的问题:
1、code2紧跟在code1后面,程序正常调用,没有问题,code2放在工程中别的位置,有的地方可以,有的地方不行(貌似越靠程序流程前面,调用就会正常)。
2、现象:出问题的时候,有两种现象,他们是我把调用代码放在不同的地方出现的:一种是dll能正常调用,但发现在LoadLibrary之后,当前类的指针this就变成了0x00000000,退出当前函数,程序就崩溃;另一种情况是调试的时候,跟到long t = getTime(3, 5);这一行,程序就没有了反应,好像在里面出不来了,没往下执行了。
三、尝试过的方法:
1、官方说“Make sure you have 4K of scratch space at the bottom of your stack”,所以我在vs中也做了设置:“项目”属性->配置属性->链接器->系统,堆栈保留大小和堆栈提交大小设成了2097152和4096,对应十六进制100000,1000,这个值是经dumpbin /HEADERS mytest.dll查到的。
2、也试过在编译dll的时候在gcc中设置了上面的值,但也无济于事。
猜测:
1、“4K of scratch space”很可能是一个原因,但是不太清楚是否是这样设置;
2、会否是因为对话框程序在切换对话框后另启了一个线程,导致无法读到原来堆栈的bottom信息;
3、编译dll的时候是否还有别的option要加,因为奇怪的是:如果我的dll里面是一个简单的加法运算的方法,程序调用是完全没有问题的!但是我的dll源文件里面加入了用来做一个获取当前时间的方法,程序调用就出现了本文的问题。
希望在这里有缘碰到刚好在这方面有经验的朋友给予赐教,感谢你花时间看我的问题!
|
Hey gey!
I've ever encountered the problem like you,eventually I resolved it. I benefit from the website as: http://blog.csdn.net/null_shadow/article/details/1807797
Mind that:you should keep the stackbase alive,so that everytime you call the dll,you have the stack called, assembler would help you!
Best luck!
I've ever encountered the problem like you,eventually I resolved it. I benefit from the website as: http://blog.csdn.net/null_shadow/article/details/1807797
Mind that:you should keep the stackbase alive,so that everytime you call the dll,you have the stack called, assembler would help you!
Best luck!
|
what if you isolate the method having the function call defined in sys/time.h? will it crash as well?