如何在 Ox 中写入一个 dll 创建的文件?
How to write to a dll-created file in Ox?
我正在尝试通过本机 fprint() ox 函数写入在外部 c++ dll 中创建的文件。
我的C++代码是(灵感来自GnuDraw C.Bos包的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
}
我收到以下错误消息:"Debug Assertion Error" in close.cpp Expression (_osfile(fh) & FOPEN) .
我找到了一个类似的post (here ) but the answer (to use /MTd or /MDd -ie change the runtime) doesn't work. I can overcome this issue by creating a new fprintf function in C and calling it form Ox ( it works) but I would prefer to use the native ox fprint function. I think this problem can be linked to this one,最后到下面的问题:how to pass a file pointer from c to ox in windows ?
最后我认为这是不可能的,这是由所谓的Dll boundaries restriction引起的:文件句柄根据C-Run-time库实现不同在编译时使用。显然我可以传递文件指针,但是 Ox 无法识别文件句柄的结构(其 CRT 结构)。
然后,除非我的 dll 是针对用于编译 ox 的 C Run-time 库的完全相同版本编译的,否则它不会工作。这可以通过与 C 库动态链接来克服,但由于官方 ox dll (oxwin.dll) 是使用静态链接编译的 (如 header “Ox Professional version 7.10 (Windows_64/U /MT)” ) 这不是一个选项。所以无论我使用哪个选项来编译我的 DLL,Ox 总是有它自己的 CRT 库副本和它自己的堆管理器。
最后,我认为写入在外部 dll 中打开的文件(对于 windows)的最佳方法是创建一个新的 C 函数:fprint_dll() 位于与open/close 文件并从 ox 调用它的那个。
基本上不对 "native" dll 之外的文件句柄执行 I/O 操作。
另请参阅:
我正在尝试通过本机 fprint() ox 函数写入在外部 c++ dll 中创建的文件。
我的C++代码是(灵感来自GnuDraw C.Bos包的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
}
我收到以下错误消息:"Debug Assertion Error" in close.cpp Expression (_osfile(fh) & FOPEN) .
我找到了一个类似的post (here ) but the answer (to use /MTd or /MDd -ie change the runtime) doesn't work. I can overcome this issue by creating a new fprintf function in C and calling it form Ox ( it works) but I would prefer to use the native ox fprint function. I think this problem can be linked to this one,最后到下面的问题:how to pass a file pointer from c to ox in windows ?
最后我认为这是不可能的,这是由所谓的Dll boundaries restriction引起的:文件句柄根据C-Run-time库实现不同在编译时使用。显然我可以传递文件指针,但是 Ox 无法识别文件句柄的结构(其 CRT 结构)。
然后,除非我的 dll 是针对用于编译 ox 的 C Run-time 库的完全相同版本编译的,否则它不会工作。这可以通过与 C 库动态链接来克服,但由于官方 ox dll (oxwin.dll) 是使用静态链接编译的 (如 header “Ox Professional version 7.10 (Windows_64/U /MT)” ) 这不是一个选项。所以无论我使用哪个选项来编译我的 DLL,Ox 总是有它自己的 CRT 库副本和它自己的堆管理器。
最后,我认为写入在外部 dll 中打开的文件(对于 windows)的最佳方法是创建一个新的 C 函数:fprint_dll() 位于与open/close 文件并从 ox 调用它的那个。
基本上不对 "native" dll 之外的文件句柄执行 I/O 操作。
另请参阅: