C#的问题< - > C++ DLLImport"试图读取或写入受保护的内存."

Chr*_*ris 6 c# c++ reference dllimport

我有一个C++ DLL,其中有一个函数,我试图从C#应用程序调用.

这是C++头文件中的代码

extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40],
                UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode);
Run Code Online (Sandbox Code Playgroud)

这是C++源文件中的代码

int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40],
                UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode)
{

    string strConfigID="12111";                                     //5 bytes
    string strFrmRev="1.25....";                                    //8 bytes
    string strDevName="ABC-123.................................";   //40 bytes

    for (int i=0;i<5;i++)
        ConfigID[i] = strConfigID[i];

    for (int i=0;i<8;i++)
        FrmRev[i] = strFrmRev[i];

    for (int i=0;i<40;i++)
        DevName[i] = strDevName[i];
    return eCode;
}
Run Code Online (Sandbox Code Playgroud)

这是C#相关代码

[DllImport("LabelStoring.dll")]
static extern int LabelStoringSSDsim(
    int devNum,
    byte[] strserial,
    byte[] strwwn,
    [In] ref byte[] ConfigID,
    [In] ref byte[] FrmRev,
    [In] ref byte[] DevName,
    int eCode
);


int errNum = LabelStoringSSDsim(devNum, bserial, bwwn, ref ConfigID, ref FrmRev, ref DevName, 123123);
Run Code Online (Sandbox Code Playgroud)

因此,当我到达最后一段代码时,我得到"尝试读取或写入受保护的内存.这通常表明其他内存已损坏." 错误.

我没有像这样导入DLL的经验,我已经做了很多搜索,但似乎无法找到问题的解决方案.

我尝试从头开始用一个简单的函数返回一个整数,这是有效的.然后我为我添加了一个int传递给函数,它仍然有效.然后我添加了一个字节数组供我通过,这有效.然后我试图将该字节数组转换为引用,但它失败了.所以我的猜测是我正在错误地收回数据.

任何帮助是极大的赞赏.

Sam*_*uce 6

尝试[In]改为[In, Out].我也不确定在一个参数上同时使用ref[In, Out]关键字.(编辑:Hans Passant在下面的评论中很好地解释了两者之间的差异.)

有关详细信息,请参阅此MSDN文章,特别是段落,"默认情况下,由于性能原因,值传递的引用类型(类,数组,字符串和接口)被封送为In参数.除非您看到这些类型的更改将InAttribute和OutAttribute(或只是OutAttribute)应用于方法参数."

  • 对,就是那样.ref或out说明符(通过引用传递)使它成为指针的指针,因为数组已经是引用类型.[In]和[Out]没有任何效果,它们只是告诉编组员什么时候需要复制指向的值.[In,Out]是默认值,如果您不关心非托管代码所做的任何修改,请省略[Out].这是一个优化. (2认同)