2013-08-02 60 views
6

Tôi đang phát triển một c .dll cần được truy cập từ chương trình C#. Lý tưởng nhất, các .dll sẽ nhận được bất kỳ cấu trúc được xác định trong C# và làm một cái gì đó với nó. Vì vậy, ban đầu, loại cấu trúc và kích thước chưa được biết cho dll C. Tôi đã có thể vượt qua các cấu trúc thông qua các chức năng bên ngoài C, và nó là supossed để được nhận được alright, nhưng, là có một cách để tìm ra kích thước và đặc điểm của cấu trúc này nhận được? có cách nào để lặp lại các thành viên của nó không?lặp qua cấu trúc không xác định c được truyền từ C#

Đây là chức năng C định nghĩa cho các dll

extern int __cdecl testCSharp(mystruct * Test){ 

//sizeof(Test) is 4, so it is ok 

for(int i=0;i < sizeof(Test) ; i++){ 

    char * value = (char*) Test; //This access the first element. 
    cout << value << endl; //Prints "some random string", so, it is received ok 
} 

return 1; 

}

Đây là mã C#

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)] 
unsafe public struct myStruct{ 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value1; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value2; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value3; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value4; 
}; 

[DllImport("SMKcomUploadDLL.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int testCSharp(ref myStruct message); 

static void Main() 
{ 
    int result; 

    myStruct message = new myStruct(); 

    message.value1 = "Some randome string"; 
    message.value2 = "0"; 
    message.value3 = "olkujhikvb"; 
    message.value4 = "isabedfbfmlk"; 

    result = testCSharp(ref message); 
} 

Tất cả các loại là String trong C#, và nó được suppossed để vẫn như vậy, vì vậy nó là điều duy nhất tôi biết về cấu trúc sẽ được thông qua.

Bất kỳ ý tưởng nào?

Cảm ơn trước

+0

Bạn có ý nghĩa gì bởi * "nên nhận bất kỳ cấu trúc nào được xác định trong C#" *? C++ cũng như C# là các ngôn ngữ đánh máy tĩnh. Vì vậy, tất cả các loại được biết đến tại thời gian biên dịch trên cả hai mặt. Hơn nữa, các định nghĩa của các loại trên cả hai mặt phải nhất quán, vì vậy việc đầm lầy có thể được thực hiện mà không có bất kỳ vấn đề gì. – Nawaz

+2

Tôi không nghĩ toán tử 'sizeof' làm những gì bạn nghĩ. 'sizeof (Test)' trả về 4 vì kích thước của một nhà thơ là 4 byte (trên máy 32 bit). Điều này không có nghĩa là có 4 mục trong Kiểm tra ... – PoByBolek

+0

@PoByBolek - Tôi không thể hiểu mã này đang làm gì, bởi vì không thể tưởng tượng được lời giải thích "đơn giản" này. – SChepurin

Trả lời

2

Khi bạn đang marshalling chúng như ByValTStr với chiều dài 100, tôi không chắc chắn bạn sẽ có thể làm việc bất kỳ bất kỳ nhiều hơn những gì bạn đã có (tức là phần tử đầu tiên).

Từ các loại MSDN (here)

.NET Framework ByValTStr hành xử giống như chuỗi C-phong cách, kích thước cố định bên trong một cấu trúc (ví dụ, char s [5])

Nếu bạn sử dụng LPStr hoặc LPWStr null-chấm dứt thay vì bạn sẽ có thể làm việc ra độ dài của họ.