C从dll写入文件,在应用程序中打开文件

C从dll写入文件,在应用程序中打开文件,c,dll,printf,C,Dll,Printf,我有一个从dll导出的文件指针,它由应用程序初始化(fopen),然后在dll中使用(fprintf) 问题是fprintf将引发异常 DLLFile.c #define BUILD_FOO #include "API.H" File *pFile; void exportedFunction() { fprintf(pFile,"This will result in an exception\n");//<-This print will crash } 应用程序.C #u

我有一个从dll导出的文件指针,它由应用程序初始化(fopen),然后在dll中使用(fprintf)

问题是fprintf将引发异常

DLLFile.c

#define BUILD_FOO
#include "API.H"

File *pFile;

void exportedFunction()
{
   fprintf(pFile,"This will result in an exception\n");//<-This print will crash
}
应用程序.C

#undef BUILD_FOO
#include "API.H"
void main()
{
pFile = fopen("path_to_folder","wt");
fprintf(pFile , "This print will work"); // <- This will be printed ok
exportedFunction(); 
}
#未定义构建
#包括“API.H”
void main()
{
pFile=fopen(“路径到文件夹”,“wt”);

fprintf(pFile,“此打印将起作用”);//让应用程序向DLL传递一个回调,在该回调中,让应用程序向文件写入。

让应用程序向DLL传递一个回调,在该回调中,让应用程序向文件写入。

这可能是由应用程序和DLL引起的。除非它们都是根据编译的trong>exact同一版本的C运行时,所有的赌注都是无效的,您不能使用来自另一个运行时的数据从一个运行时调用CRT函数,反之亦然

避免此问题的最安全方法是不要跨DLL边界传递
文件*
指针。这样,与
文件*
的任何交互都将始终使用同一版本的CRT进行,并且不会出现任何不匹配的危险。因此,DLL不应公开
文件*
变量;相反,它应该是不透明的类型,并且对变量的所有操作都需要在同一个模块中进行

例如:

// API.h
FOOAPI void set_file(void *file);
FOOAPI void set_fprintf_callback(int (*my_fprintf)(void *, const char *, ...));
FOOAPI void exportedFunction();

// DLLFile.c
void *pFile;  // Not exported
int (*fprintf_callback)(void *, const char *, ...);  // Not exported

FOOAPI set_file(void *file)
{
    pFile = file;
}

FOOAPI set_fprintf_callback(int (*my_fprintf)(void *, const char *, ...))
{
    fprintf_callback = my_fprintf;
}

FOOAPI exportedFunction()
{
    // Call back into the application to do the actual fprintf
    fprintf_callback(pFile, "This should not crash");
}

// Application.c
int mydll_fprintf(void *pFile, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int result = vfprintf((FILE *)pFile, fmt, ap);
    va_end(ap);

    return result;
}

int main()
{
    FILE *pFile = fopen(...);
    set_file(pFile);
    set_fprintf_callback(&mydll_fprintf);
    exportedFunction();

    return 0;
}

这可能是由您的应用程序和DLL引起的。除非它们都是针对相同版本的C运行时编译的,否则所有的赌注都是无效的,并且您不能使用来自另一个的数据从一个调用CRT函数,反之亦然

避免此问题的最安全方法是不跨DLL边界传递
FILE*
pointer。这样,与
FILE*
的任何交互都将始终使用相同版本的CRT进行,并且不会出现任何不匹配的危险。因此,DLL不应暴露
FILE*
变量;相反,它应该是不透明的类型,并且对变量的所有操作都需要在同一个模块中进行

例如:

// API.h
FOOAPI void set_file(void *file);
FOOAPI void set_fprintf_callback(int (*my_fprintf)(void *, const char *, ...));
FOOAPI void exportedFunction();

// DLLFile.c
void *pFile;  // Not exported
int (*fprintf_callback)(void *, const char *, ...);  // Not exported

FOOAPI set_file(void *file)
{
    pFile = file;
}

FOOAPI set_fprintf_callback(int (*my_fprintf)(void *, const char *, ...))
{
    fprintf_callback = my_fprintf;
}

FOOAPI exportedFunction()
{
    // Call back into the application to do the actual fprintf
    fprintf_callback(pFile, "This should not crash");
}

// Application.c
int mydll_fprintf(void *pFile, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int result = vfprintf((FILE *)pFile, fmt, ap);
    va_end(ap);

    return result;
}

int main()
{
    FILE *pFile = fopen(...);
    set_file(pFile);
    set_fprintf_callback(&mydll_fprintf);
    exportedFunction();

    return 0;
}
这个答案可能有用这个答案可能有用