0

我正在尝试通过本机 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 -即更改运行时)不起作用。我可以通过在 C 中创建一个新的 fprintf 函数并从 Ox 调用它(它可以工作)来克服这个问题,但我更喜欢使用本机 ox fprint 函数。我认为这个问题可以链接到这个问题,最后是以下问题:如何将文件指针从 c 传递给 windows 中的 ox ?

4

1 回答 1

1

最后我认为这是不可能的,这是由所谓的Dll 边界限制引起的:文件句柄的实现方式与编译时使用的 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 相同的 dll 中牛。

基本上不使用其“本机” dll 之外的文件句柄执行 I/O 操作。

也可以看看 :

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

C 运行时对象,dll 边界

于 2015-12-29T11:18:51.980 回答