linux下C C++调用C#

旧的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的返回值是不一样,说明是环境的问题。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页