为什么 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,否则会再次出现同样的问题。