C从dll写入文件,在应用程序中打开文件
我有一个从dll导出的文件指针,它由应用程序初始化(fopen),然后在dll中使用(fprintf) 问题是fprintf将引发异常 DLLFile.cC从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
#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;
}
这个答案可能有用这个答案可能有用