IntPtr未正确编组为单声道

时间:2015-06-24 20:30:47

标签: c# c++ mono marshalling ubuntu-14.04

我正在尝试在Ubuntu 14.04上使用Mono执行P / Invoke函数:

[DllImport(@"libRT", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    private static extern uint DoChallenge(
        IntPtr pEncryptedBlob,
        uint dwEncryptedBlobLen,
        IntPtr pDecryptedBlob,
        uint dwMaxLen,
        ref uint dwDecryptedBlobLen);

在我调用C#中的函数之前,我打印加密和解密的值:

Console.WriteLine(pEncryptedBlob.ToString()); // value is 140640247632608
Console.WriteLine(pDecryptedBlob.ToString()); // values is 140640247634240

// Do the challenge
this.errorCode = DoRtasChallenge(pEncryptedBlob, pDecryptedBlob,
                    (uint)this.decryptedBlobBuffer.Length,
                    ref this.decryptedBlobReturnLength);

现在在C ++代码中我打印我收到的值:

APIFUNC uint32_t DoChallenge(unsigned char * pEncryptedBlob,long dwEncryptedBlobLen,unsigned char * pDecryptedBlob,long dwMaxLen,long * dwDecryptedBlobLen)
{ 
    fprintf(stderr, "pEncryptedBlob: %ld \n",pEncryptedBlob);
    fprintf(stderr, "pDecryptedBlob: %ld \n",pDecryptedBlob);

    // the output: 
    // pEncryptedBlob: 1 
    // pDecryptedBlob: 140640603072256 
}

因此看起来两个IntPtrs在编组过程中都会被修改。

我认为这种情况特别是因为Mono / Ubuntu 14.04 64位环境,因为它适用于Windows和Ubuntu 14.04 32位。

有关解决方法的任何想法?非常感谢

2 个答案:

答案 0 :(得分:2)

删除特定于平台的实施,以便您的C#& c / cpp代码将运行xplat你应该只将C#“System.String”传递给“const char * src”。 Interop编组将处理剩下的工作。

C签名:

void myfunc (const char *src, size_t n);

C#DllImport of:

private static extern void myCfunc (string src, uint n);

用法:

var myString = "Test";
myCfunc(myString, myString.Length);

与本机库互操作: http://www.mono-project.com/docs/advanced/pinvoke/

答案 1 :(得分:-1)

我刚刚找到一个解决方法,我强迫我的IntPtrs被编组为4个字节:

[DllImport(@"libRT", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern uint DoChallenge(
    [MarshalAs(UnmanagedType.U4)] // this is a fix
    IntPtr pEncryptedBlob,
    uint dwEncryptedBlobLen,
    [MarshalAs(UnmanagedType.U4)]
    IntPtr pDecryptedBlob,
    uint dwMaxLen,
    ref uint dwDecryptedBlobLen);

结果:

C#结果:

139700723537696
139700723538064

C ++结果:

pEncryptedBlob: 139700723537696 
pDecryptedBlob: 139700723538064