如何在 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 操作。

另请参阅:

https://support.microsoft.com/en-us/kb/140584

C Runtime objects, dll boundaries