linux下C C++呼叫C#
阿新 • • 發佈:2019-02-18
舊的MFC專案呼叫的一些庫用C#來寫(編譯成DLL庫),現在專案要移植到linux下,也想在linux下用C來呼叫C#,linux不支援C#,需要安裝linux下C#的執行環境mono。
呼叫原理大概是這樣子的,linux下的C/C++不能直接呼叫C#函式的,而是通過mono提供的api,建立一個C#的執行環境,在該環境中建立C#類,再通過mono api間接呼叫C#。
mono的安裝參考www.mono-project.com官網的,直接用apt-get安裝即可,很方便。
callcsharp.cpp
#include <mono/jit/jit.h> #include <mono/metadata/assembly.h> #include <mono/metadata/debug-helpers.h> #include <assert.h> #include <stdio.h> #define print(fmt, args...) printf(fmt "\n", ##args); #define TRUE 1 #define FALSE 0 #define USE_OLD_LIB 0 int main() { const char *dlllib = "./DataMatrixLibrary.dll"; MonoDomain *domain = mono_jit_init("Mydomain"); if (!domain) { print("domain is null"); } MonoAssembly *assembly = mono_domain_assembly_open(domain, dlllib); if (!assembly) { print("assembly is null"); return -1; } MonoImage *image = mono_assembly_get_image(assembly); if (!image) { print("image is null"); return -1; } //-----------------------------------------------------------------> /* //這裡是對C#類中static函式的引腳,比較簡單,不用建立類 MonoMethodDesc *desc_static = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:Test", TRUE); if (!desc_static) { print("desc_static is null"); return -1; } MonoMethod *method_static = mono_method_desc_search_in_image(desc_static, image); if (!method_static) { print("method_static is null"); return -1; } mono_runtime_invoke(method_static, NULL, NULL, NULL); */ //DataMatrixLibrary是namespace,AisDataMatrix是類 MonoClass *my_class = mono_class_from_name(image, "DataMatrixLibrary", "AisDataMatrix"); if (!my_class) { print("my_class is null"); return -1; } //建立類 MonoObject *class_instance = mono_object_new(domain, my_class); if (!class_instance) { print("class instance is null"); return -1; } //呼叫類的construct函式,沒有引數,如果有引數,參考mono的文件,裡邊有介紹怎樣呼叫有引數的建構函式 mono_runtime_object_init(class_instance); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 //獲取函式說明,最後一個引數為TRUE表示第一個引數要包括namespace MonoMethodDesc *desc_SetBarcodeAngle = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarCodeAngel", TRUE); #else MonoMethodDesc *desc_SetBarcodeAngle = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeAngel", TRUE); #endif if (!desc_SetBarcodeAngle) { print("desc is null"); return -1; } //找到該函式 MonoMethod *method_SetBarcodeAngle = mono_method_desc_search_in_image(desc_SetBarcodeAngle, image); if (!method_SetBarcodeAngle) { print("method is null"); return -1; } //呼叫C#函式,返回值我沒處理,mono文件有介紹怎樣獲取返回值 void *args[1]; int angel = 10; args[0] = &angel; mono_runtime_invoke(method_SetBarcodeAngle, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetFontFamily = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetFontFamily", TRUE); #else MonoMethodDesc *desc_SetFontFamily = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeFontFamily", TRUE); #endif if (!desc_SetFontFamily) { print("desc_SetFontFamily is null"); return -1; } MonoMethod *method_SetFontFamily = mono_method_desc_search_in_image(desc_SetFontFamily, image); if (!method_SetFontFamily) { print("method_SetFontFamily is null"); return -1; } args[0] = mono_string_new(domain, "Arial"); mono_runtime_invoke(method_SetFontFamily, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetBarCodeFormat = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarCodeFormat", TRUE); #else MonoMethodDesc *desc_SetBarCodeFormat = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeFormat", TRUE); #endif if (!desc_SetBarCodeFormat) { print("desc_SetBarCodeFormat is null"); return -1; } MonoMethod *method_SetBarCodeFormat = mono_method_desc_search_in_image(desc_SetBarCodeFormat, image); if (!method_SetBarCodeFormat) { print("method_SetBarCodeFormat is null"); return -1; } int bar_format = 0; args[0] = &bar_format; mono_runtime_invoke(method_SetBarCodeFormat, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetBarCodeWidth = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarCodeWidth", TRUE); #else MonoMethodDesc *desc_SetBarCodeWidth = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeWidth", TRUE); #endif if (!desc_SetBarCodeWidth) { print("desc_SetBarCodeWidth is null"); return -1; } MonoMethod *method_SetBarCodeWidth = mono_method_desc_search_in_image(desc_SetBarCodeWidth, image); if (!method_SetBarCodeWidth) { print("method_SetBarCodeFormat is null"); return -1; } int codeWidth = 555; args[0] = &codeWidth; mono_runtime_invoke(method_SetBarCodeWidth, class_instance, args, NULL); //-----------------------------------------------------------------> MonoMethodDesc *desc_SetImageWidth = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetImageWidth", TRUE); if (!desc_SetImageWidth) { print("desc is null"); return -1; } MonoMethod *method_SetImageWidth = mono_method_desc_search_in_image(desc_SetImageWidth, image); if (!method_SetImageWidth) { print("method_SetImageWidth is null"); return -1; } int imageWidth = 569; args[0] = &imageWidth; mono_runtime_invoke(method_SetImageWidth, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetIsNegative = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetIsNegative", TRUE); #else MonoMethodDesc *desc_SetIsNegative = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeNegative", TRUE); #endif if (!desc_SetIsNegative) { print("desc is null"); return -1; } MonoMethod *method_SetIsNegative = mono_method_desc_search_in_image(desc_SetIsNegative, image); if (!method_SetIsNegative) { print("method_SetIsNegative is null"); return -1; } int isNeg = 1; args[0] = &isNeg; mono_runtime_invoke(method_SetIsNegative, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetIsVertical = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetIsVertical", TRUE); #else MonoMethodDesc *desc_SetIsVertical = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeFlip", TRUE); #endif if (!desc_SetIsVertical) { print("desc_SetIsVertical is null"); return -1; } MonoMethod *method_SetIsVertical = mono_method_desc_search_in_image(desc_SetIsVertical, image); if (!method_SetIsVertical) { print("method_SetIsVertical is null"); return -1; } int isVer = 1; args[0] = &isVer; mono_runtime_invoke(method_SetIsVertical, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetIsMirror = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetIsMirror", TRUE); #else MonoMethodDesc *desc_SetIsMirror = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetBarcodeMirror", TRUE); #endif if (!desc_SetIsMirror) { print("desc is null"); return -1; } MonoMethod *method_SetIsMirror = mono_method_desc_search_in_image(desc_SetIsMirror, image); if (!method_SetIsMirror) { print("method_SetIsMirror null"); return -1; } int isMirror = 1; args[0] = &isMirror; mono_runtime_invoke(method_SetIsMirror, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_SetImageBackColor = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetImageBackColor", TRUE); #else MonoMethodDesc *desc_SetImageBackColor = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:SetImageBackground", TRUE); #endif if (!desc_SetImageBackColor) { print("desc_SetImageBackColor is null"); return -1; } MonoMethod *method_SetImageBackColor = mono_method_desc_search_in_image(desc_SetImageBackColor, image); if (!method_SetImageBackColor) { print("method_SetImageBackColor null"); return -1; } int imageBackcolor = 1; args[0] = &imageBackcolor; mono_runtime_invoke(method_SetImageBackColor, class_instance, args, NULL); //-----------------------------------------------------------------> #if USE_OLD_LIB > 0 MonoMethodDesc *desc_CreateFile = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:CreateFile", TRUE); #else MonoMethodDesc *desc_CreateFile = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:CreateBarcodeFile", TRUE); #endif if (!desc_CreateFile) { print("desc_CreateFile is null"); return -1; } MonoMethod *method_CreateFile = mono_method_desc_search_in_image(desc_CreateFile, image); if (!method_CreateFile) { print("method_CreateFile null"); return -1; } //這個函式有兩個string引數 void *args2[2]; args2[0] = mono_string_new(domain, "0017362S123E123RX+LLSSSCCF1"); args2[1] = mono_string_new(domain, "/home/i/csharp"); mono_runtime_invoke(method_CreateFile, class_instance, args2, NULL); /* MonoMethodDesc *desc_GetBarCodeSize = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:GetBarCodeSize", TRUE); if (!desc) { print("desc is null"); return -1; } int codeWidth = 555; args[0] = &codeWidth; mono_runtime_invoke(method_SetBarCodeWidth, class_instance, args, NULL) MonoMethodDesc *desc_CreateByte = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:CreateByte", TRUE); if (!desc) { print("desc is null"); return -1; } int codeWidth = 555; args[0] = &codeWidth; mono_runtime_invoke(method_SetBarCodeWidth, class_instance, args, NULL) MonoMethodDesc *desc_CreateBmp = mono_method_desc_new("DataMatrixLibrary.AisDataMatrix:CreateBmp", TRUE); if (!desc) { print("desc is null"); return -1; } int codeWidth = 555; args[0] = &codeWidth; mono_runtime_invoke(method_SetBarCodeWidth, class_instance, args, NULL) */ mono_jit_cleanup(domain); print("call c# success!!!"); return 0; }
編譯:
g++ -o callcsharp callcsharp.cpp `pkg-config --cflags --libs mono-2`
mono庫安裝在/usr/lib/mono下。
能呼叫C#,但是發現mono對C#支援不是很好,有些庫函式執行不正常,分另在linux和windows對比測試,呼叫函式時引數都是一樣(可以在C#用System.console.write指印出來),但是Linux和windows的返回值是不一樣,說明是環境的問題。