Trong khi lain đánh tôi để viết một ví dụ, tôi sẽ đăng nó dù sao đi nữa chỉ trong trường hợp ...
Quá trình viết một wrapper để truy cập thư viện riêng của bạn giống như truy cập một trong các thư viện chuẩn .Net.
Ví dụ C# mã lớp trong một dự án có tên CsharpProject:
using System;
namespace CsharpProject {
public class CsharpClass {
public string Name { get; set; }
public int Value { get; set; }
public string GetDisplayString() {
return string.Format("{0}: {1}", this.Name, this.Value);
}
}
}
Bạn sẽ tạo ra một thư viện C++ Dự án lớp quản lý (ví dụ là CsharpWrapper) và thêm dự án # C của bạn như là một tham chiếu đến nó. Để sử dụng cùng một tệp tiêu đề để sử dụng nội bộ và trong dự án tham chiếu, bạn cần một cách để sử dụng đúng declspec. Điều này có thể được thực hiện bằng cách xác định một chỉ thị tiền xử lý (CSHARPWRAPPER_EXPORTS
trong trường hợp này) và sử dụng một #ifdef
để thiết lập macro xuất khẩu trong giao diện C/C++ của bạn trong một tệp tiêu đề. Tệp tiêu đề giao diện không được quản lý phải chứa nội dung không được quản lý (hoặc đã được bộ lọc tiền lọc lọc ra).
Tệp tiêu đề giao diện C++ không được quản lý (CppInterface).h):
#pragma once
#include <string>
// Sets the interface function's decoration as export or import
#ifdef CSHARPWRAPPER_EXPORTS
#define EXPORT_SPEC __declspec(dllexport)
#else
#define EXPORT_SPEC __declspec(dllimport)
#endif
// Unmanaged interface functions must use all unmanaged types
EXPORT_SPEC std::string GetDisplayString(const char * pName, int iValue);
Sau đó, bạn có thể tạo tệp tiêu đề nội bộ để có thể đưa vào tệp thư viện được quản lý của mình. Điều này sẽ thêm các câu lệnh using namespace
và có thể bao gồm các hàm trợ giúp mà bạn cần.
Managed C++ tập tin giao diện Header (CsharpInterface.h):
#pragma once
#include <string>
// .Net System Namespaces
using namespace System;
using namespace System::Runtime::InteropServices;
// C# Projects
using namespace CsharpProject;
//////////////////////////////////////////////////
// String Conversion Functions
inline
String^ToManagedString(const char * pString) {
return Marshal::PtrToStringAnsi(IntPtr((char *) pString));
}
inline
const std::string ToStdString(String^strString) {
IntPtr ptrString = IntPtr::Zero;
std::string strStdString;
try {
ptrString = Marshal::StringToHGlobalAnsi(strString);
strStdString = (char *) ptrString.ToPointer();
}
finally {
if (ptrString != IntPtr::Zero) {
Marshal::FreeHGlobal(ptrString);
}
}
return strStdString;
}
Sau đó, bạn chỉ cần viết mã giao diện của bạn mà không được gói.
Managed tập C++ Interface Nguồn (CppInterface.cpp):
#include "CppInterface.h"
#include "CsharpInterface.h"
std::string GetDisplayString(const char * pName, int iValue) {
CsharpClass^oCsharpObject = gcnew CsharpClass();
oCsharpObject->Name = ToManagedString(pName);
oCsharpObject->Value = iValue;
return ToStdString(oCsharpObject->GetDisplayString());
}
Sau đó chỉ cần bao gồm tiêu đề không được quản lý trong dự án không được quản lý của bạn, hãy cho mối liên kết để sử dụng file .lib tạo ra khi liên kết, và chắc chắn rằng .Net và các wrapper DLL nằm trong cùng thư mục với ứng dụng không được quản lý của bạn.
#include <stdlib.h>
// Include the wrapper header
#include "CppInterface.h"
void main() {
// Call the unmanaged wrapper function
std::string strDisplayString = GetDisplayString("Test", 123);
// Do something with it
printf("%s\n", strDisplayString.c_str());
}
Giao diện bạn muốn hiển thị với C/C++ không được quản lý phức tạp đến mức nào? – CuppM
Xem liên kết này để có câu hỏi/câu trả lời tương tự: http://stackoverflow.com/questions/13293888/how-to-call-ac-sharp-library-from-native-c-using-c-cli-and-ijw . – amalgamate