2011-02-07 31 views
5

Tôi muốn sử dụng hàm C++ gốc của mình từ dll trong mã C# được quản lý. Nhưng chức năng của tôi có các đối số như std :: vector & - tham chiếu vectơ ... Làm thế nào tôi có thể thực hiện đối số này trong câu lệnh dllimport? Tôi biết ví dụ rằng có IntPtr và như vậy nhưng những gì sẽ được cho std :: vector <>?Sử dụng mã C++ gốc trong C# - vấn đề với std :: vector

+1

Điều này có thể sẽ rất khó, nếu không phải là không thể. Bạn có thể cung cấp giao diện 'C' cho thư viện' C++ 'của bạn và sử dụng nó thay vào đó không? – ereOn

+2

Sử dụng C++/CLI để tạo các lớp trình bao bọc. –

+1

Trong khi bạn có thể sử dụng các giải pháp sugested để đạt được một cái gì đó tương tự như những gì bạn cần, nếu tôi hiểu chính xác bạn kiểm soát cả mã cho dll không được quản lý và ứng dụng được quản lý.Trong trường hợp này có lẽ nó sẽ là tốt hơn để cung cấp C++/CLI wrappers cho các chức năng của bạn trong dll và gọi chúng trực tiếp từ C#. Có lẽ bạn cũng nên xem STL.Net. Đây là một liên kết đến một mồi: http://msdn.microsoft.com/en-us/library/ms379600%28v=vs.80%29.aspx – ds27680

Trả lời

5

Tôi sẽ xuất các hàm "C" bọc chức năng cần thiết và P/Gọi chúng từ C#. Hàm "C" như vậy có thể phơi bày dữ liệu std::vector<> dưới dạng con trỏ và kích thước của bộ đệm dữ liệu.

Nói ví dụ rằng bạn có một std::vector<byte_t> trong một lớp học Buffer:

class Buffer 
{ 
public: 
    const std::vector<byte_t>& GetData() const { return data_; } 

private: 
    std::vector<byte_t> data_; 
}; 

Sau đó, bạn có thể xuất khẩu một "C" chức năng để đúng phạm vi các Buffer bạn muốn sử dụng:

Buffer* CreateBuffer(); 

Và bạn có thể muốn làm điều gì đó ở bên gốc điền vào số std::vector<byte_t> với dữ liệu:

void DoSomethingThatProduceData(Buffer* buffer); 

Sau đó, bạn có thể đọc dữ liệu:

void GetBufferData(const Buffer* buffer, const byte_t** data, int* size); 

Và cuối cùng, dọn dẹp:

void DestroyBuffer(Buffer* buffer); 

Dịch những tuyên bố "C" để P/Gọi những người trên C# bên:

[DllImport("YourBufferLib.dll")] 
static extern IntPtr CreateBuffer(); 

[DllImport("YourBufferLib.dll")] 
static extern void DoSomethingThatProduceData(IntPtr buffer); 

[DllImport("YourBufferLib.dll")] 
static extern void GetBufferData(IntPtr buffer, out IntPtr data, out Int32 size); 

[DllImport("YourBufferLib.dll")] 
static extern void DestroyBuffer(IntPtr buffer); 

Sẽ là một điều tốt để bao bọc các cuộc gọi đó trên phía được quản lý trong lớp IDisposable đảm bảo rằng tài nguyên gốc là đúng eaned up.

[Các, hơi tầm thường, chi tiết thực hiện các chức năng "C" rõ ràng là trái như một bài tập cho người đọc.]

0

vector STL là phương pháp templated không được quản lý. Về lý thuyết, bạn có thể tính toán bù trừ cho các phương pháp tương ứng của vector làm một số thế hệ mã và gọi nó. Bạn không thể sử dụng DllImport vì các vectơ STL là một thư viện mẫu chỉ là các phương thức không được xuất. Bạn có thể tất nhiên viết một wrapper C phong cách để gọi các phương thức cụ thể như

int GetSize(vector<xxx> *vec) 
{ 
    return vec.size(); 
} 

Nhưng bạn không muốn làm điều đó bởi vì nhiều hiệu ứng chuyển tiếp unmanged quản lý cần thiết cho việc này sẽ mang lại ứng dụng của bạn để ngăn chặn một bất ngờ. Nếu bạn cần thao tác các vectơ stl, tốt nhất là sử dụng C++ được quản lý và gọi từ C# vào tập tin Managed C++ để thao tác các vectơ theo ý muốn. Ở nhiều công ty, việc sử dụng Managed C++ bị cấm bởi vì mọi người không chú ý đến chi phí của các quá trình chuyển đổi không được quản lý mà đã khiến C++ mất tài sản chính của nó: Tốc độ.

Yours, Alois Kraus