如何调用C#委托从本机C最简单的方式传递字符串数组?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何调用C#委托从本机C最简单的方式传递字符串数组?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3219字,纯文字阅读大概需要5分钟。
内容图文
![如何调用C#委托从本机C最简单的方式传递字符串数组?](/upload/InfoBanner/zyjiaocheng/810/1f3c37f5c18544b6af73ef6ef8fc9425.jpg)
我知道这可以通过在C中进行mallocing,将malloced指针传递给参数类型为IntPtr的委托,将编组传递给string []然后使用托管代码中的单独导出的C函数释放malloced内存来完成.
我的问题是:这可以做得更简单吗?例如. :
> C#delegate参数的类型为string []?
>没有单独的自由函数来从托管代码调用
编辑:我试过代理签名:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
MyManagedDelegate(string[] values, int valueCount)
和C中的功能:
void NativeCallDelegate(char *pStringValues[], int nValues)
{
if (gSetStringValuesCB)
gSetStringValuesCB(pStringValues, nValues);
}
在C中调用它:
char *Values[]= {"One", "Two", "Three"};
NativeCallDelegate(Values, 3);
这导致我只能在数组中使用第一个字符串.
解决方法:
这是如何正确地完成它,我将给出一个完整的例子,以便它可以重现.
C方面
typedef void(*setStringValuesCB_t)(char *pStringValues[], int nValues);
static setStringValuesCB_t gSetStringValuesCB;
void NativeCallDelegate(char *pStringValues[], int nValues)
{
if (gSetStringValuesCB)
gSetStringValuesCB(pStringValues, nValues);
}
__declspec(dllexport) void NativeLibCall(setStringValuesCB_t callback)
{
gSetStringValuesCB = callback;
char *Values[] = { "One", "Two", "Three" };
NativeCallDelegate(Values, 3);
}
这里没什么好看的,我只是添加了必要的胶水代码,剩下的就是其余的.
C#方面
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void MyManagedDelegate(
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)]
string[] values,
int valueCount);
[DllImport("NativeTemp", CallingConvention = CallingConvention.Cdecl)]
public static extern void NativeLibCall(MyManagedDelegate callback);
public static void Main()
{
NativeLibCall(PrintReceivedData);
}
public static void PrintReceivedData(string[] values, int valueCount)
{
foreach (var item in values)
Console.WriteLine(item);
}
诀窍在于编组部分:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void MyManagedDelegate(
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)]
string[] values,
int valueCount);
MarshalAs属性告诉.NET封送程序如下:
> UnmanagedType.LPArray你得到一个数组……
> ArraySubType = UnmanagedType.LPStr …标准C字符串…
> SizeParamIndex = 1 …并且该数组的大小由第二个参数指定.
在调用C#方法之前,.NET编组器会复制C字符串并将其转换为System.String实例.因此,如果您需要将动态生成的字符串传递给C#,则将它们malloc,然后调用gSetStringValuesCB,之后可以立即释放它们,全部来自C代码,因为.NET具有自己的数据副本.
你可以参考the docs:
UnmanagedType.LPArray
:A pointer to the first element of a C-style array. When marshaling from managed to unmanaged code, the length of the array is determined by the length of the managed array. When marshaling from unmanaged to managed code, the length of the array is determined from the
MarshalAsAttribute.SizeConst
andMarshalAsAttribute.SizeParamIndex
fields, optionally followed by the unmanaged type of the elements within the array when it is necessary to differentiate among string types.
UnmanagedType.LPStr:
A single byte, null-terminated ANSI character string. You can use this member on the
System.String
andSystem.Text.StringBuilder
data types.
MarshalAs.SizeParamIndex:
Indicates the zero-based parameter that contains the count of array elements, similar to
size_is
in COM.
内容总结
以上是互联网集市为您收集整理的如何调用C#委托从本机C最简单的方式传递字符串数组?全部内容,希望文章能够帮你解决如何调用C#委托从本机C最简单的方式传递字符串数组?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。