当某些参数是委托时,是不是可以在 C# 中使用“C++ 库函数”?

Posted

技术标签:

【中文标题】当某些参数是委托时,是不是可以在 C# 中使用“C++ 库函数”?【英文标题】: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 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

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

以上是关于当某些参数是委托时,是不是可以在 C# 中使用“C++ 库函数”?的主要内容,如果未能解决你的问题,请参考以下文章

C#事件是否委托

C#中的委托是啥?事件是否一种委托?

c#中委托的作用是啥?

C# 委托

C#里事件和委托有啥区别啊??

c#中的委托01