2011-02-07 17 views
5

Chcę używać moich natywnych funkcji C++ z biblioteki dll w zarządzanym kodzie C#. Ale moje funkcje przyjmują argumenty takie jak std :: vector & - wektor odniesienia ... Jak mogę wdrożyć ten argument w oświadczeniu dllimport? Wiem na przykład, że istnieją IntPtr i tak dalej, ale co będzie dla std :: vector <>?Używanie natywnego kodu C++ w c ​​# - problem ze std :: vector

+1

Prawdopodobnie będzie to bardzo trudne, jeśli nie niemożliwe. Czy możesz podać interfejs 'C' dla swojej biblioteki' C++ 'i użyć go zamiast tego? – ereOn

+2

Skorzystaj z C++/CLI do tworzenia klas otoki. –

+1

Chociaż można użyć sugerowanych rozwiązań, aby osiągnąć coś podobnego do tego, czego potrzebujesz, jeśli dobrze rozumiem, kontrolujesz zarówno kod dla niezarządzanej biblioteki DLL, jak i zarządzanej aplikacji.W tym przypadku może lepiej byłoby zapewnić wrappery C++/CLI dla twoich funkcji w bibliotece dll i wywołać je bezpośrednio z C#. Może powinieneś również rzucić okiem na STL.Net. Tutaj jest łącze do elementu startera: http://msdn.microsoft.com/en-us/library/ms379600%28v=vs.80%29.aspx – ds27680

Odpowiedz

5

Chciałbym eksportować funkcje "C", które zawijają potrzebną funkcjonalność i P/Wywołać je z C#. Taka funkcja "C" może wystawiać dane std::vector<> jako wskaźnik i rozmiar bufora danych.

powiedzieć na przykład, że masz std::vector<byte_t> w klasie Buffer:

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

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

Następnie można wyeksportować funkcję prawidłowo Zakres "C" The Buffer chcesz użyć:

Buffer* CreateBuffer(); 

Prawdopodobnie chcesz zrobić coś po stronie natywnej, która wypełni std::vector<byte_t> danymi:

void DoSomethingThatProduceData(Buffer* buffer); 

Następnie można przeczytać, że dane:

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

i ostatni, oczyścić:

void DestroyBuffer(Buffer* buffer); 

Przekłada te deklaracje "", aby P/Invoke te po stronie C#:

[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); 

Byłoby dobrze aby opakować te wywołania po zarządzanej stronie w klasie IDisposable, która zapewnia, że ​​rodzimy zasób jest prawidłowo cl podniósł słuchawkę.

[W, nieco trywialne, szczegóły realizacji funkcji „C” są oczywiście lewo wykonywania dla czytelnika.]

0

STL wektory są zarządzane na matrycy metodami. Teoretycznie możesz obliczyć przesunięcia do odpowiednich metod wektora, wygenerować kod i wywołać go. Nie można używać DllImport, ponieważ wektory STL są biblioteką tylko do szablonu, które nie zostały wyeksportowane. Można oczywiście pisać otoki C stylu zadzwonić specyficzne metody jak

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

Ale nie chcesz tego zrobić, ponieważ wiele zarządzanych unmanged przejścia potrzebne do tego przyniesie swoją aplikację do nagłego zatrzymania. Jeśli potrzebujesz manipulować wektorami stl, najlepiej jest użyć zarządzanego C++ i wywołać z C# do biblioteki dll Managed C++, aby manipulować wektorami, jak chcesz. W wielu firmach używanie Managed C++ było zakazane, ponieważ ludzie nie zwracali uwagi na koszty zarządzanych niezarządzanych przejść, które spowodowały, że C++ straciło swój główny atut: szybkość.

Pozdrawiam, Alois Kraus

Powiązane problemy