我正在尝试在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位。
有关解决方法的任何想法?非常感谢
答案 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);
答案 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