C# 为什么在调用导入的C++;来自C代码的函数?
我已经读了很多关于这个话题的文章,但是我还没有找到解决问题的方法 <>从我的C代码中,我尝试用<代码> dLimPurt调用C++函数。不幸的是,我没有C++代码,但是头文件给出了函数的信息:C# 为什么在调用导入的C++;来自C代码的函数?,c#,c++,marshalling,dllimport,access-violation,C#,C++,Marshalling,Dllimport,Access Violation,我已经读了很多关于这个话题的文章,但是我还没有找到解决问题的方法 从我的C代码中,我尝试用 dLimPurt调用C++函数。不幸的是,我没有C++代码,但是头文件给出了函数的信息: ABCD Initialize ( IN FLOAT a , IN DWORD b ); ABCD也在头文件中定义: #define EFGH extern "C" ... #define ABCD EFGH __declspec(dllexport) HRESULT WINAPI 在C#代码
ABCD Initialize
(
IN FLOAT a
, IN DWORD b
);
ABCD也在头文件中定义:
#define EFGH extern "C"
...
#define ABCD EFGH __declspec(dllexport) HRESULT WINAPI
在C#代码中,我尝试像这样调用Initialize函数:
[DllImport("path.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern UInt32 Initialize([In] float a, [In] UInt32 b);
...
Initialize(50.0f, 0);
根据需要,数据类型float
不需要编组,我可以使用UInt32
代替DWORD
。对于返回类型,HRESULT WINAPI
,我使用数据类型UInt32
,据我所知,也不需要编组?(我还尝试对参数和返回值使用其他数据类型,但总是得到相同的异常)
对于DllImport属性,已经测试了字符集
和调用约定
的许多可能性,但没有成功。在声明函数时,我还尝试了两种变体,包括参数的[In]
属性
调用函数时,会引发异常:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
我是不是遗漏了什么?成功调用函数的下一步是什么
多谢各位
这是完整的C代码。如上所述,我没有用于构建.dll文件的代码。此外,我不允许共享dll
using System;
using System.Runtime.InteropServices;
namespace MyNamespace
{
class Program
{
[DllImport("path.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern UInt32 Initialize([In] float a, [In] UInt32 b);
static void Main(string[] args)
{
Initialize(50.0f, 0); // <- throws System.AccessViolationException
Console.ReadLine();
}
}
}
使用系统;
使用System.Runtime.InteropServices;
名称空间MyNamespace
{
班级计划
{
[dlliport(“path.dll”,CharSet=CharSet.Unicode,CallingConvention=CallingConvention.StdCall)]
公共静态外部UInt32初始化([In]浮点a,[In]UInt32 b);
静态void Main(字符串[]参数)
{
初始化(50.0f,0);//最后,我可以确定问题
为了检查参数的数据类型和返回值,我在dll上使用了反编译器Snowman。看起来dll只定义了接口,实现在另一个dll文件中,开发人员忘记了首先发送
一旦第二个.dll文件存储在我的程序的runtime文件夹中,函数调用就会工作。我还想指出的是,该调用可以使用[in]
参数属性,也可以不使用[in]
参数属性
虽然我不知道抛出异常的确切原因AccessViolationException:试图读取或写入受保护内存…
(我认为另一个异常可能更适合这里),但我很高兴这个问题能够得到解决
感谢Ben Voigt和David Heffernan的评论!如本文所述,该代码是正确的。我敢打赌,当您更改真实代码时,您转录了一些内容。请出示a。感谢您的评论!不幸的是,我不允许共享.dll文件,因此我无法提供可复制的示例。C#代码已接近完成,名称空间由一个类组成,该类的主函数只调用Initialize(50.0f,0)当然,你可以分享一个可重复的例子。只要删掉任何敏感的东西。DavidHeffernan编辑了这个问题并添加了完整的C代码。不幸的是我没有用于构建C++ DLL的代码。而且,我不允许共享.dll文件或部分。标题文件的相关部分可以在问题中找到。遗憾的是,我不允许发布完整的.h文件。希望这有帮助。谢谢您的时间。@luk:我可以通过向您保证[in]来为您节省一些组合供您试用这里不需要使用
。这是x86或x64代码还是其他体系结构?有些人比其他人更关心调用约定。WINAPI
应该按照您的p/invoke已经指定的设置stdcall。