为什么 Dll 不能导出参数类型为 FILE* 的函数
Why Dll can't export a function with parameter type FILE*
这是 Dll 代码
#ifdef HELLO_EXPORTS
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
CLASS_DECLSPEC FILE* GetStdout() {
return stdout;
}
CLASS_DECLSPEC void dump_code(FILE* fd, const void* data, size_t len)
{
unsigned char* p = (unsigned char*)data;
size_t i;
for(i = 1; i < len + 1; ++i){
fprintf(fd, "0x%.2x, ", p[i-1]);
if((i%16)==0) fprintf(fd, "\n");
}
fprintf(fd, "\n");
}
这是测试代码:
#include <stdio.h>
#include <stdlib.h>
#include "dump.h"
int main(){
char data[] = {
0x1f,0xc2,0x8b,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xc3,0x8d,0xc2,0x90,0x3d
};
dump_code(GetStdout(), data, 16);
//dump_code(stdout, data, 16);
}
如果我直接使用标准输出:dump_code(stdout, data, 16);
,程序会在_lock_file崩溃。
但是可以使用 GetStdout() 而不是标准输出。
不要在两个 libc 副本之间传递 FILE *
指针。您需要 link exe 和 dll 针对与动态 link 库完全相同的 libc 版本,否则它将无法工作。
Windows 的一般传统是甚至不要尝试让这种事情起作用。对于每个会 return 分配内存的导出,都有另一个导出来释放该内存,更复杂的事情要么根本没有完成,要么使用 COM 提供清理例程完成。
OP 现在评论说他使用 /MTd
构建静态库,解码为 multi-threaded,并切换到 /MDd
,解码为 multi-threaded dll-version-specific 库(位于 .dll 中)按预期解决了问题。切换到release时,必须使用/MD
而不是/MT
,否则会再次出现同样的问题。
这是 Dll 代码
#ifdef HELLO_EXPORTS
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
CLASS_DECLSPEC FILE* GetStdout() {
return stdout;
}
CLASS_DECLSPEC void dump_code(FILE* fd, const void* data, size_t len)
{
unsigned char* p = (unsigned char*)data;
size_t i;
for(i = 1; i < len + 1; ++i){
fprintf(fd, "0x%.2x, ", p[i-1]);
if((i%16)==0) fprintf(fd, "\n");
}
fprintf(fd, "\n");
}
这是测试代码:
#include <stdio.h>
#include <stdlib.h>
#include "dump.h"
int main(){
char data[] = {
0x1f,0xc2,0x8b,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xc3,0x8d,0xc2,0x90,0x3d
};
dump_code(GetStdout(), data, 16);
//dump_code(stdout, data, 16);
}
如果我直接使用标准输出:dump_code(stdout, data, 16);
,程序会在_lock_file崩溃。
但是可以使用 GetStdout() 而不是标准输出。
不要在两个 libc 副本之间传递 FILE *
指针。您需要 link exe 和 dll 针对与动态 link 库完全相同的 libc 版本,否则它将无法工作。
Windows 的一般传统是甚至不要尝试让这种事情起作用。对于每个会 return 分配内存的导出,都有另一个导出来释放该内存,更复杂的事情要么根本没有完成,要么使用 COM 提供清理例程完成。
OP 现在评论说他使用 /MTd
构建静态库,解码为 multi-threaded,并切换到 /MDd
,解码为 multi-threaded dll-version-specific 库(位于 .dll 中)按预期解决了问题。切换到release时,必须使用/MD
而不是/MT
,否则会再次出现同样的问题。