2010-11-17 70 views
2

我有以下C头/代码示例:C#编组为C结构和功能


头文件


struct category_info { 
int id; 
const char *name; 
const char *description; 
}; 


DLLEXPORT 
void* xyz_categories_info(struct category_info **info, size_t *info_count); 

例C片段


struct category_info *catinfo; 

size_t catcount; 
size_t i; 
int max_name_len = 0; 
void *catmem = xyz_categories_info(&catinfo, &catcount) 


,我想转换为C#...

我第一次的猜测(和它的猜测)是:

[StructLayout(LayoutKind.Sequential)] 
    public struct category_info 
    { 
     int id; 
     [MarshalAs(UnmanagedType.LPStr)] 
     StringBuilder name; 
     [MarshalAs(UnmanagedType.LPStr)] 
     StringBuilder description; 
    }; 

函数[DllImport(“MYDLL。 dll“,CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr xyz_categories_info([Out] category_info cat,[Out] int catSize);

,但它只是看起来不正确的..

任何建议。一旦上述在C#中声明正确..应该如何在C#中

category_info catinfo; 

catmem = xyz_categories_info访问( out catinfo,out 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); 
+0

xyz_categories_info究竟是什么?看看它的原型,我可以猜测它分配了category_info结构数组,并将指针指向此数组及其大小以输出参数。它返回什么?你的C代码片段不包含这些信息。 – 2010-11-17 12:03:15

+0

请发布完整的C代码片断,其中显示了如何使用和释放由此函数返回的信息。使用低级别的Marshal函数和IntPtr类型,我们可以编写几乎所有的C语言,尽管在C++/CLI中这样做确实非常痛苦。 – 2010-11-17 12:45:52

+0

这对Alex有帮助吗? – user296191 2010-11-29 10:22:59

回答

1

此代码已编译,但未经过测试。如果你知道C,你会理解这里发生了什么,这只是转换为C#的相同C代码。

 
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); 
       } 
      } 
     } 
    } 
} 
+0

绝对完美... !!!! Works 100%... – user296191 2010-11-29 11:17:05

+0

Thankyou非常非常... – user296191 2010-11-29 11:18:00

0

这是一个导入的DLL功能

[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
public static extern IntPtr xyz_categories_info([Out]category_info cat, [Out]int catSize); 

但不知道该OUT的是

struct category_info { 
int id; 
const char *name; 
const char *description; 
}; 

我bilive应该是C#类

你的C代码正确

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) 

这在C#什么我不知道的为size_t将不得不在C#中的类,但那时,类必须与DLL类完全匹配,否则会出现类型不匹配这是加载跨语言错误的问题DLLS

该DLL应该做什么?也许我们可以帮助