C#调用C ++第三方DLL(无源)引发异常 - 不是PInvoke兼容 [英] C# calling C++ 3rd party DLL (no source) raises exception - not PInvoke Compatible

查看:287
本文介绍了C#调用C ++第三方DLL(无源)引发异常 - 不是PInvoke兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用VS 2015社区与ASP.NET MVC Web应用程序,使用第三方C ++ DLL我没有源代码。文档很稀缺,因为与第三方DLL的作者进行任何有用的交流。

I am using VS 2015 Community with an ASP.NET MVC Web Application that uses a 3rd party C++ DLL I do not have source code for. Documentation is very scarce as is any helpful communication with the authors of the 3rd party DLL.

我问过一个相关的问题并从@Steven接收到一个好的答案。我已经根据他的答案修改了我的代码,我试图成功调用第三方C ++ DLL。代码:

I've asked a related SO Question and received a good answer from @Steven. I've modified my code according to his answer and am trying to make a successful call to the 3rd party C++ DLL. The code:

MyDLLInput _DLLInput = new MyDLLInput();
{
    SomeList = new int[288],
    ...
    SomeInt = 22,
    SomeDbl = 1.45,
    ...
    PathtoData = "C:\\Some\\Path\\To\\Data"
};    

var ids = new int[] { 0, 12, 33, 67, 93 };
Array.Copy(ids, _DLLInput.SomeList, ids.Length);

// Call DLL Entry Point
MyDLLOutput _DLLOutput = MyDLL.Unit(_DLLInput);

引发例外:


方法的类型签名不符合PInvoke兼容

// C#输入STRUCT

// C# Input STRUCT

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyDLLInput
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
    public int[] SomeList;
    ...
    public int SomeInt;
    public double SomeDbl;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string PathtoData;
};

// C#输出STRUCT

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyDLLOutput
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
    public int[] SomeList;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
    public double[] SomeDblArray;
    ...
    public int SomeInt;        // Same as input
    public double SomeDbl;     // Same as input
}

// C#DLLImport

public class MyDLL
{
    [DllImport("My_DLL.dll",
        EntryPoint = "?Unit@@YA?AUDLLOutput@@UDLLInput@@@Z",
        CallingConvention = CallingConvention.Cdecl)]
    public static extern MyDLLOutput Unit(MyDLLInput UnitInput);
}

// C ++ My_DLL.h >

// C++ My_DLL.h

#define  EPS_API __declspec(dllexport) 

struct DLLInput
{
    int SomeList[288];

    int SomeInt;
    double SomeDbl;

    char PathtoData[256];
};

struct DLLOutput
{
    int SomeList[288];
    double SomeDblArray[288];
    ...
    int SomeInt;
    double SomeDbl;
};

EPS_API DLLOutput Unit(DLLInput UnitInput);

我认为我必须接近,但未能找到任何SO或Google结果帮帮我。有人看到我做错了吗?

I think I must be close, but haven't been able to find any SO or Google results that help. Does anyone see what I'm doing wrong?

推荐答案

扩展Ben的说法。

您需要将const定义删除到可互操作的结构之外。通过声明结构的布局是顺序的,编译器期望EXACTLY相同数量的成员,在EXACTLY中声明相同的顺序,每个类型声明,EXACTLY两边相同的大小(即在C ++和C#)。 const 声明添加到内存布局,因此签名不兼容。

You need to remove the const definitions to outside the interopable struct. By declaring a layout of the struct as sequential the compiler is expecting EXACTLY the same number of members, declared in EXACTLY the same order, with each type declared, EXACTLY the same size on both sides (i.e in C++ and C#). Those const declarations add to the memory layout and so the signatures are not compatible.

char 在C#和C ++中不是相同的大小, byte 是(尽管它们可以根据平台而改变,位)。你可以编组一个 byte 数组,而不是 string ,但是要么就可以。

char is not the same size in C# and C++, byte is (although they can change depending on the platform, both types are guaranteed at least 8 bits). You could marshall a byte array instead of a string, but either is fine.

创建与C ++ char 数组(相同大小)兼容的字节数组。

To Create a byte array which is compatible with C++ char array (same size).

UTF8Encoding utf8 = new UTF8Encoding();
public byte[] PathToData = new byte[256];
PathToData = utf8.GetBytes(pathToDataString);

另一方面,如果文档很少,作者没有帮助,关于使用此第三方。调用它是一回事,调试它是另一回事。

On another note though, if documentation is scarce and the authors are not helpful, personally I would think twice about using this 3rd party. Calling it is one thing, debugging it is another.

这篇关于C#调用C ++第三方DLL(无源)引发异常 - 不是PInvoke兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆