C结构和函数的C#编组
我有以下C头/代码示例:C结构和函数的C#编组,c#,marshalling,C#,Marshalling,我有以下C头/代码示例: 头文件 示例C代码段 我想把它转换成c# 我的第一个猜测是: [DllImport(“mydll.dll”,CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)] 公共静态外部IntPtr xyz_类别信息([Out]类别信息类别,[Out]int catSize) 但是看起来不太对劲 有什么建议吗。。一旦在C#中正确声明了上述内容。。如何在C#中访问它 catmem=xyz_类别_信
头文件
示例C代码段
我想把它转换成c# 我的第一个猜测是: [DllImport(“mydll.dll”,CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
公共静态外部IntPtr xyz_类别信息([Out]类别信息类别,[Out]int catSize) 但是看起来不太对劲 有什么建议吗。。一旦在C#中正确声明了上述内容。。如何在C#中访问它 catmem=xyz_类别_信息(输出catinfo,输出catcount) 非常感谢您的帮助 谢谢 ================================================================================ 更新2 在xyz_categories_info中分配的内存通过以下C调用释放:
void xyz_categories_info_free(void *p);
下面是一个在C中使用的示例。。。。希望这能解释得更清楚一点
category_buffer = xyz_categories_info(&category_info, &category_count);
if( !category_buffer )
{
// Failed Log a message and exit.
exit(1);
}
for(j=0; j<category_count; j++)
{
if( category_info[j].id == 0 )
continue;
printf("id: %d name: '%s' description: '%s'\n",
category_info[j].id,
category_info[j].name,
category_info[j].description
);
}
xyz_categories_info_free(category_buffer);
category\u buffer=xyz\u categories\u info(&category\u info,&category\u count);
如果(!类别_缓冲区)
{
//未能记录消息并退出。
出口(1);
}
对于(j=0;j这对于导入DLL函数是正确的
[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr xyz_categories_info([Out]category_info cat, [Out]int catSize);
但我不确定这是怎么回事
你的C代码是什么
struct category_info {
int id;
const char *name;
const char *description;
};
我的双语应该是C级的
至于使用它和代码,我不知道你想做什么
size_t catcount;
size_t i;
int max_name_len = 0;
void *catmem = xyz_categories_info(&catinfo, &catcount)
这在C#我不确定as size#t必须是C#中的一个类,但该类必须与DLL类完全匹配,否则会出现类型不匹配这就是加载跨语言DLL的问题
这个DLL应该在做什么?也许我们可以帮你这段代码是编译的,但没有经过测试。如果你懂C,你就会明白这里发生了什么,这就是翻译成C的C代码
使用制度;
使用System.Collections.Generic;
使用系统文本;
使用System.Runtime.InteropServices;
命名空间控制台应用程序1
{
公共结构类别信息
{
公共int id;
公共IntPtr名称;
公共IntPtr描述;
};
班级计划
{
[DllImport(“mydll.dll”,CallingConvention=CallingConvention.Cdecl)]
公共静态外部IntPtr xyz_类别信息(参考IntPtr类别,参考int catSize);
[DllImport(“mydll.dll”,CallingConvention=CallingConvention.Cdecl)]
公共静态外部无效xyz_类别信息免费(IntPtr cat);
静态void Main(字符串[]参数)
{
IntPtr类别=IntPtr.0;
IntPtr category_buffer=IntPtr.Zero;
int category_count=0;
类别信息=新类别信息();
IntPtr电流;
尝试
{
类别缓冲区=xyz类别信息(参考类别、参考类别计数);
if(类别缓冲区==IntPtr.Zero)
{
返回;
}
如果(类别计数==0)
{
返回;
}
对于(int j=0;j xyz_categories_info到底是什么?看看它的原型,我可以猜到它分配了categories_info结构的数组,并将指向该数组的指针及其大小放置到输出参数中。它返回什么?您的C代码片段不包含此信息。请发布完整的C代码片段,其中显示了此fu如何返回信息使用低级封送处理函数和IntPtr类型,我们几乎可以编写C所做的一切,尽管在C++/CLI中这样做确实更好。
category_buffer = xyz_categories_info(&category_info, &category_count);
if( !category_buffer )
{
// Failed Log a message and exit.
exit(1);
}
for(j=0; j<category_count; j++)
{
if( category_info[j].id == 0 )
continue;
printf("id: %d name: '%s' description: '%s'\n",
category_info[j].id,
category_info[j].name,
category_info[j].description
);
}
xyz_categories_info_free(category_buffer);
[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr xyz_categories_info([Out]category_info cat, [Out]int catSize);
struct category_info {
int id;
const char *name;
const char *description;
};
public class category_info
{
public const string name {get; set};
public const string description {get; set};
public int id {get; set;}
public category_info(int id, const string name, const string description){
this.name = name;
this.description = description;
this.id = id;
}
}
size_t catcount;
size_t i;
int max_name_len = 0;
void *catmem = xyz_categories_info(&catinfo, &catcount)
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
public struct category_info
{
public int id;
public IntPtr name;
public IntPtr description;
};
class Program
{
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr xyz_categories_info(ref IntPtr cat, ref int catSize);
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void xyz_categories_info_free(IntPtr cat);
static void Main(string[] args)
{
IntPtr categories = IntPtr.Zero;
IntPtr category_buffer = IntPtr.Zero;
int category_count = 0;
category_info info = new category_info();
IntPtr current;
try
{
category_buffer = xyz_categories_info(ref categories, ref category_count);
if (category_buffer == IntPtr.Zero)
{
return;
}
if (category_count == 0)
{
return;
}
for (int j = 0; j < category_count; j++)
{
if (IntPtr.Size == 4)
{
current = new IntPtr(categories.ToInt32() + j * Marshal.SizeOf(info));
}
else
{
current = new IntPtr(categories.ToInt64() + j * Marshal.SizeOf(info));
}
info = (category_info)Marshal.PtrToStructure(current, typeof(category_info));
if (info.id == 0)
{
continue;
}
Console.WriteLine(info.id);
Console.WriteLine(Marshal.PtrToStringAnsi(info.name));
Console.WriteLine(Marshal.PtrToStringAnsi(info.description));
}
}
finally
{
if (category_buffer != IntPtr.Zero)
{
xyz_categories_info_free(category_buffer);
}
}
}
}
}