2010-11-17 71 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應該做什麼?也許我們可以幫助