C# 如何创建c++\非托管c dll的cli包装器

C# 如何创建c++\非托管c dll的cli包装器,c#,c++,c,c++-cli,C#,C++,C,C++ Cli,我可能会把自己弄糊涂了,但以前从未这样做过,稍微说明一下方向会很有帮助。 我试图从C应用程序调用一些C代码。我尝试过使用PInvoke,但发现它有点棘手。我想我会尝试做一个C++\CLI包装器 有些复杂的结构具有可变长度的双数组,很难用PInvoke处理 我读过一些关于如何做到这一点的书,但我不明白。我发现的大部分内容都与包装C++有关,而不是C。C代码已经在从Java应用程序及其JNA服务导出其功能。我有C代码、头、库和dll,但我不想对现有的任何东西进行更改,以免打乱其他消费应用程序。调用它

我可能会把自己弄糊涂了,但以前从未这样做过,稍微说明一下方向会很有帮助。
我试图从
C
应用程序调用一些
C
代码。我尝试过使用PInvoke,但发现它有点棘手。我想我会尝试做一个
C++\CLI
包装器

有些复杂的结构具有可变长度的双数组,很难用
PInvoke
处理
我读过一些关于如何做到这一点的书,但我不明白。我发现的大部分内容都与包装
C++
有关,而不是
C
C
代码已经在从Java应用程序及其
JNA
服务导出其功能。我有
C
代码、头、库和dll,但我不想对现有的任何东西进行更改,以免打乱其他消费应用程序。调用它的
C#
应用程序将是64位的,大多数示例都是创建win32库,这有关系吗

更新:在下面添加代码:
注意:这只是几个函数中的一个,可能是最简单的一个,但它们都非常相似

C HEADER:
typedef struct myStruct_t
{
    double prefix[8];
    int length;
    double array[1];
}
myStruct;

C:
extern "C" __declspec( dllexport ) myStruct *doSomething(const myStruct *input, double a)
{
    myStruct *output;
    //doSomething
    return output;
}

包裹C和C++之间的差别很小。您需要创建一个C++/CLI类库。然后,在托管本地代码的托管C++类中编写函数。 例如,假设DLL导出此函数:

int sqr(int x)
然后在类库中包含头文件:

#include <mynativelibrary.h>

你可以在C++代码中使用这个程序集,就像其他任何程序集一样。

< P> C和C++之间的包的差别非常小。您需要创建一个C++/CLI类库。然后,在托管本地代码的托管C++类中编写函数。 例如,假设DLL导出此函数:

int sqr(int x)
然后在类库中包含头文件:

#include <mynativelibrary.h>

你可以在C++代码中使用这个程序集,就像其他任何程序集一样。

< P> C和C++之间的包的差别非常小。您需要创建一个C++/CLI类库。然后,在托管本地代码的托管C++类中编写函数。 例如,假设DLL导出此函数:

int sqr(int x)
然后在类库中包含头文件:

#include <mynativelibrary.h>

你可以在C++代码中使用这个程序集,就像其他任何程序集一样。

< P> C和C++之间的包的差别非常小。您需要创建一个C++/CLI类库。然后,在托管本地代码的托管C++类中编写函数。 例如,假设DLL导出此函数:

int sqr(int x)
然后在类库中包含头文件:

#include <mynativelibrary.h>

然后,您可以在C代码中使用此程序集,就像使用任何其他程序集一样。

我在VisualStudio 2012中创建了一些项目,它用托管代码包装了一个旧的MFC dll。我是这样做的:

  • 在中创建类库作为CLR
  • 将旧项目链接到此新项目
  • 在新项目中为函数和结构创建包装器,并调用旧代码
  • 在C代码中使用新对象
  • <请不要忘记为托管C++代码创建UNITAcess。(我总是忘记……:)


    祝你好运。

    我在VisualStudio 2012中创建了一些项目,它用托管代码包装了一个旧的MFC dll。我是这样做的:

  • 在中创建类库作为CLR
  • 将旧项目链接到此新项目
  • 在新项目中为函数和结构创建包装器,并调用旧代码
  • 在C代码中使用新对象
  • <请不要忘记为托管C++代码创建UNITAcess。(我总是忘记……:)


    祝你好运。

    我在VisualStudio 2012中创建了一些项目,它用托管代码包装了一个旧的MFC dll。我是这样做的:

  • 在中创建类库作为CLR
  • 将旧项目链接到此新项目
  • 在新项目中为函数和结构创建包装器,并调用旧代码
  • 在C代码中使用新对象
  • <请不要忘记为托管C++代码创建UNITAcess。(我总是忘记……:)


    祝你好运。

    我在VisualStudio 2012中创建了一些项目,它用托管代码包装了一个旧的MFC dll。我是这样做的:

  • 在中创建类库作为CLR
  • 将旧项目链接到此新项目
  • 在新项目中为函数和结构创建包装器,并调用旧代码
  • 在C代码中使用新对象
  • <请不要忘记为托管C++代码创建UNITAcess。(我总是忘记……:)


    祝你好运。

    如果Java可以通过jna调用你的C代码,那么通过PInvoke调用C应该没有问题。而C++互操作(使用C++ +CLI)是PInvoke(隐式pNoCKE)的一种类型,使用DLIMPORT是显式PInvoke。 当您不需要指定函数参数的封送方式,或显式调用DllImportAttribute时可以指定的任何其他详细信息,但您需要额外的C++/CLI Dll时,隐式PInvoke非常有用

    在这两种情况下,您都必须处理将本机数据类型封送到管理数据类型的问题,这是不可避免的,也是痛苦的

    在C#中,结构可以声明为:

    [StructLayout(LayoutKind.Sequential)]
        public struct myStruct {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            double prefix[] intersects;
    
            public int length;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public double[] array;
        }
    
    但对于函数,DLLImport无法处理这种情况,因为C#无法删除函数返回的非托管指针的内存,您可以在C中创建另一个wrap函数,使其使用out参数返回结果,在这种情况下,C#代码为:

    或者您可以使用C++/CLI互操作,因为它可以处理本机类型和管理类型,因此调用顺序为:

  • C#代码使用托管数据类型调用此C++/CLI函数:

    ManagedmyStruct[]doSomething(ManagedmyStruct[]输入,双a)

  • 在C++/CLI函数domSomething中,它调用na