【问题标题】:Is possible to use a "C++ Library Function" into C# when some of its parameters are delegates?当某些参数是委托时,是否可以在 C# 中使用“C++ 库函数”?
【发布时间】:2012-09-12 03:42:12
【问题描述】:

我通过
[DllImport("C:\\gaul-windows.dll", ...)] 属性将 C++ 库用于 C# 解决方案。

我需要使用一个函数,它的一些参数是委托,它返回的类型也有一些委托作为字段。

我可以这样做吗?

我之所以问,是因为我尝试使用 struct 作为返回类型,但后来我得到了这个异常:“方法的类型签名与 PInvoke 不兼容”

所以我改变了它并尝试使用 IntPtr 作为返回类型,但后来我得到了这个异常:Cannot marshal 'parameter #16': Generic types cannot be marshaled.

所以首先我想知道这是否可能?以这种方式使用这种功能。如果不可能,我将如何使用它?

编辑

我需要使用的功能

[DllImport("C:\\gaul-windows.dll", SetLastError = 真, CallingConvention = CallingConvention.Cdecl)] 公共外部静态 IntPtr ga_genesis_boolean(int population_size, int num_chromo, int len_chromo, GAgeneration_hook generation_hook, GAiteration_hook 迭代钩子, GAdata_destructor data_destructor, GAdata_ref_incrementor data_ref_incrementor, GAevaluate 评估, GAseed种子, GAadapt适应, GAselect_one select_one, GAselect_two select_two, GAmutate 变异, GAcrossover 跨界车, GAreplace替换, 诠释?用户数据);

这是其中一位代表的示例

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 公共代表短 GAselect_one( 参考人口流行, IntPtr 母亲);

超过Here你可以得到全班。

最后这是我对函数的调用

var x = Gaul.ga_genesis_boolean(30, /* const int population_size */ vehicle_num, /* const int num_chromo */ order_num, /* const int len_chromo */ IntPtr.Zero,// null, /* GAgeneration_hook generation_hook */ null, /* GAiteration_hook 迭代钩子 */ null, /* GAdata_destructor data_destructor */ null, /* GAdata_ref_incrementor data_ref_incrementor */ new GAevaluate(darp_score),/* GAevaluate 评估 */ new GAseed(Gaul.ga_seed_boolean_random), /* GAseed 种子 */ null, /* GAadapt 适应 */ new GAselect_one(Gaul.ga_select_one_bestof2),/* GAselect_one select_one */ new GAselect_two(Gaul.ga_select_two_bestof2),/* GAselect_two select_two */ new GAmutate(Gaul.ga_mutate_boolean_singlepoint), /* GAmutate mutate */ new GAcrossover(Gaul.ga_crossover_boolean_singlepoints), /* GAcrossover 交叉 */ null, /* GAreplace 替换 */ null /* vpointer 用户数据 */ );

【问题讨论】:

  • 这是一个 CLI/C++ 库吗?
  • 不,不是。它是一组用 C++ 编译的函数,旨在通过导入而不是 C++ 项目中的命令行来使用。
  • 您的用户数据应该是 IntPtr。如果您将人口声明为类,则可以使用它返回您的函数。
  • 我也可以建议使用这个工具 clrinterop.codeplex.com/releases/view/14120

标签: c# c++ interop dllimport gaul


【解决方案1】:

是的,当它的某些参数是委托时,您可以使用 C++ 库函数。

我收到的错误是“无法封送'参数 #16':无法封送泛型类型。”不是关于委托参数,而是可以为空的整数。

【讨论】:

    【解决方案2】:

    DllImportAttribute 只能应用于方法定义。该方法定义定义了在 DLL 中声明的本机函数的签名。这意味着该方法必须是全局函数(并导出)并且不支持类函数。

    您不能在结构和类等类型定义上使用DllImportAttribute

    如果要从 DLL 中导入非全局函数的方法,则必须创建全局函数来包装要导入的内容。

    【讨论】:

    • 我正在尝试使用一个全局函数,它使用另一个全局委托函数作为参数。
    • 没有代码,我无法具体告诉你哪里出了问题。但是,如果您有一个本机结构,则需要在 C# 中声明该结构,以准确告诉编组器该结构在内存中的结构。这不能是泛型类型。 msdn.microsoft.com/en-us/library/ef4c3t39(v=vs.100).aspx 详细说明了如何编组结构。
    • 是的,我已经在 C# 中声明了结构。我刚刚编辑了问题以添加一些代码。还可以下载带有导入的完整类源代码,以防万一它可以帮助您找出可能不正确的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2014-06-03
    • 2011-12-04
    • 2013-04-08
    • 1970-01-01
    相关资源
    最近更新 更多