当前位置: 首页 > 编程语言 > C#

C#调用C++DLL函数的问题分享

时间:2023-04-10 10:51:59 C#

C#调用C++DLL函数的问题这是C#中的河豚问题的第三题。虽然我不能在我的应用程序中实现blowfish,但我决定将它用作外部C++DLL。请注意,我已经尝试过Blowfish.NET和其他任何一个,问题是我正在将代码从C++转换为C#,而C#代码必须与C++代码完全相同。到目前为止:—>C++DLL源代码<—请注意,导出的函数位于C#代码(定义)的末尾[DllImport("TestDLL.dll",EntryPoint="Initkey",ExactSpelling=true,CallingConvention=CallingConvention.Cdecl)]publicstaticunsafeexternvoidInitkey(byte[]key);[DllImport("TestDLL.dll",EntryPoint="encode",ExactSpelling=true,CallingConvention=CallingConvention.Cdecl)]publicstaticunsafeexternvoidencode(UInt32*stream);C#代码(函数调用)——初始化Blowfish键UInt32[]keyarray=newUInt32[2];//一些代码Extern.Initkey(Misc.ConvertFromUInt32Array(keyarray));//////用于将UInt32数组转换为字节数组的辅助函数。publicstaticbyte[]ConvertFromUInt32Array(UInt32[]array){列表结果=newList();foreach(数组中的UInt32值){byte[]converted=BitConverter.GetBytes(value);结果.AddRange(转换);}返回结果.ToArray();}-编码数据。UInt32[]keyarray2=newUInt32[2];//一些不安全的代码{fixed(UInt32*LPBYTE=keyarray2){Extern.encode(LPBYTE);在用Encode函数覆盖keyarray2之后,我通过解密检查C++代码中的值以确保一切正常。好吧,这行不通。这是我的问题,这就是我寻求您帮助的原因。当我解密的时候,值是不一样的,但是如果我在C++源代码中加密和解密,它们是一样的。C++的代码完全一样,只是没有DLL,因为代码是在C++里的。可能是Initialize函数的缘故。几个月前我读到C++中的数组作为指针传递。我不相信,但即便如此——这会是问题所在吗?我找不到线索。我用C#中的那个河豚浪费了我的生命。至少该解决方案应该有效,但它不起作用-为什么?要补充jachymko所说的内容,还要检查BitConverter的文档-您需要确保以预期的字节顺序传递密钥和数据。注意-在您之前的线程中,我使用修改后的Blowfish.NET加密器成功加密了数据,并且它与您的C++代码的结果相匹配。您是否意识到您正在初始化一个在Initkey函数返回时被销毁的临时实例?您应该将整个事情合并到一个函数中,或者在堆上创建一个cBlowfish并将指针返回到C#代码(它可以将其视为不透明的IntPtr)。另外,您不需要在这里使用unsafe。直接传递UInt32[]即可。C和C++中的数组作为指针传递。C#中数组的语义包括一个额外的间接层。您的C#程序(可能)传递保存数据地址的变量的地址。我最近一直在努力将C#中的字节数组传递给C函数,并且必须在两个方向上编组数据。对我来说,您的代码正在执行此操作并不明显。比解释更好,我将提供一个具体示例://extern"C"LIBEXIFWRAPPER_APIvoidfindEXIFtagValue(void*load,unsignedinttagID,char*buf,intbufLen);[DllImport("libexif-wrapper.dll")]unsafepublicstaticexternIntPtrfindEXIFtagValue([MarshalAs(UnmanagedType.SysUInt)]IntPtrload,inttagID,[MarshalAs(UnmanagedType.SysUInt)]IntPtrbuf,intbufLen);此函数接受一个指向不透明数据的指针、一个int和一个用于存储文本字符串的字节数组。下面的代码片段展示了如何声明字节数组,将其传递给C函数并提取结果:constinttagBuffer=1024;IntPtrbuf=Marshal.AllocHGlobal(tagBuffer);findEXIFtagValue(loader,(int)ExifTag.EXIF_TAG_DATE_TIME,buf,tagBuffer);字符串s=Marshal.PtrToStringAnsi(buf);请注意,参数在原型中编组并再次编组以检索结果。这些对我来说都不是特别明显。似乎IntPtr是void*的C#等价物,除了我必须使用SysUInt来管理(C)void*。指向作为SysUInt封送的字节数组的指针。(来自C#noob)HTH也许你应该尝试使用ref作为指针,并输出一个通过参数返回数据的函数。请让我知道它是否有效。谢谢。以上就是C#学习教程:ProblemswhencallingC++DLLfunctionsfromC#分享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: