我正在尝试通过本机fprint()ox函数写入在外部c ++ dll中创建的文件。
我的C ++代码(受到C. Bos的GnuDraw包的src代码的启发):
#define OxSetOpenFile(pv,i,d,f) (pv)[i].type = OX_FILE, (pv)[i].t.ioval.fp = d, (pv)[i].t.ioval.fmode = f
extern "C" void OXCALL fopen_C(OxVALUE *rtn, OxVALUE *pv, int cArg)
{
char *sFile;
FILE *fh;
if (cArg != 1)
OxRunError(ER_ARGS, NULL);
OxLibCheckType(OX_STRING, pv, 0, 0);
sFile = OxStr(pv, 0);
fh = fopen(sFile, "w");
if (fh == NULL)
OxRunErrorMessage("Oops, I can't open the file");
OxSetOpenFile(rtn, 0, fh, 162); //162 is found in the gnudraw src code
}
我使用Visual Studio 2015构建dll,但是我无法从ox写入此文件,以下Ox代码在fprint()函数中崩溃:
main()
{
decl fh = fopen_C("test.txt");
if(!isfile(fh))
oxrunerror("not file", 0);
fprint(fh, "test text"); /// crash here
}
我在close.cpp Expression(_osfile(fh)& FOPEN)中收到以下错误消息:“Debug Assertion Error”。
我发现了一个类似的帖子(here),但答案(使用/ MTd或/ MDd -ie更改运行时)不起作用。我可以通过在C中创建一个新的fprintf函数并将其调用为Ox(它可以工作)来克服这个问题,但我更喜欢使用原生的ox fprint函数。我认为这个问题可以链接到this one,最后是以下问题:如何在Windows中将文件指针从c传递到牛?
答案 0 :(得分:1)
最后我认为不可能,这是由所谓的Dll boundaries restriction引起的:文件句柄的编译时间与编译时使用的C-Run-time库不同。显然我可以传递文件指针但是Ox无法识别文件句柄的结构(它的CRT结构)。
然后,除非我的dll是针对用于编译ox的C运行时库的完全相同版本编译的,否则它将无效。这可以通过动态链接到C库来克服,但由于官方的ox dll(oxwin.dll)是使用静态链接编译的(如标题“Ox Professional版本7.10(Windows_64 / U / MT )“)它不是一种选择。因此,无论我使用哪个选项来编译我的DLL,Ox都将拥有自己的CRT库副本和自己的堆管理器。
最后我认为写入外部dll(对于windows)打开的文件的最佳方法是创建一个新的C函数:fprint_dll()位于与打开/关闭文件的文件相同的dll中从牛那里叫它。
基本上不使用" native"之外的文件句柄执行I / O操作。 DLL。
另见: