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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C是一种高级编程语言,被广泛用于系统级编程和开发各种应用程序。 首先,调用C意味着在其他编程语言或系统中使用C语言编写的函数、库、模块或代码。这种调用通常是为了利用C的性能和底层访问能力。为了调用C,需要在其他编程语言中使用相应的接口或包装器来调用C函数。 例如,在Python中,可以使用ctypes模块来调用C函数。通过将C函数声明为ctypes库中的特殊类型,并指定参数和返回值的类型,就可以通过Python调用C函数。这样可以在Python中使用C语言的功能,如高速计算和对底层硬件的直接访问。 另外一种常见的调用C的方式是通过使用C++编写C++包装器或接口来实现。C++作为一种支持面向对象编程的语言,可以更好地与C对接,使用C++包装C的函数和数据结构,并提供更高级的接口和功能。这样,其他语言可以调用C++包装器,进而调用C语言的功能。 总结来说,调用C意味着使用其他编程语言或系统中的代码和功能,这些代码和功能是由C语言编写的。这种调用可以通过使用特定的接口或包装器来实现,以便在其他编程语言中使用C的性能和低级别访问能力。通过调用C,我们可以利用C语言的强大功能,并与其他语言的代码进行无缝集成。 ### 回答2: C是一种编程语言,它可以通过编写源代码并编译后调用。在C中,调用指的是调用函数或执行特定的代码段。 要调用C程序,首先需要编写C源代码。使用一个文本编辑器,例如记事本或专门的代码编辑器,编写C代码。C代码通常以.c文件的形式保存。 在C代码中,可以定义函数。要调用这些函数,需要在代码的适当位置使用函数名加上括号,并传入相应的参数。例如,以下是一个简单的C函数调用的示例: ``` #include <stdio.h> void myFunction(int num) { printf("The number is %d", num); } int main() { int x = 5; myFunction(x); return 0; } ``` 在上面的示例中,定义了一个名为myFunction的函数,该函数接受一个整数参数,并在控制台输出该数字。在主函数中,声明一个整数变量x并赋值为5,然后调用myFunction函数,并将x作为参数传递给它。 要调用C程序,需要使用C编译器将源代码编译为可执行文件。例如,使用GNU C编译器(GCC)可以执行以下命令来编译上面的示例代码并生成可执行文件: ``` gcc example.c -o example ``` 在此命令中,使用gcc命令指定使用GCC编译器,example.c是源代码文件的名称,-o选项用于指定生成的可执行文件的名称。 完成编译后,可以执行可执行文件以运行C程序。在命令行或终端中,执行以下命令来运行上面的示例程序: ``` ./example ``` 执行该命令后,应该会在控制台中看到输出消息:“The number is 5”。 这就是调用C程序的基本过程。编写C源代码,通过编译器编译为可执行文件,然后执行可执行文件来运行程序。 ### 回答3: C调用C指的是使用一种编程语言C来调用另一种编程语言C的功能或代码。 C作为一种低级语言,提供了底层的硬件访问和操作能力,而且广泛用于系统级编程和嵌入式开发。C语言的特点包括简洁、高效、灵活和可移植性强。 当需要使用C语言所不具备的特定功能时,可以通过C调用其他编程语言,以扩充C语言的能力。通常会使用C语言的某些机制,如函数调用、链接库等来实现C调用C的操作。 具体实现C调用C的方式有多种,其中比较常见的有以下几种: 1. 使用接口函数:在C代码中定义一个接口函数,其函数体中调用其他编程语言实现的函数或模块。C代码通过调用接口函数来间接使用其他编程语言的功能。 2. 使用链接库:将其他编程语言实现的代码编译成链接库(也称为动态链接库或共享库),然后在C代码中通过链接库的接口来调用其中的函数。 3. 使用系统调用:一些操作系统提供了系统调用的功能,可以通过系统调用调用其他编程语言实现的功能。例如,在Linux系统中可以使用系统调用来执行Shell脚本,间接实现C调用其他编程语言。 需要注意的是,C调用C需要保证两者的兼容性,主要包括函数参数的类型和返回值的类型等方面。另外,C调用C的操作可能会涉及到内存管理和数据交换等问题,需要谨慎处理,以确保程序的正确性和健壮性。 总之,C调用C是一种扩展C语言功能的方式,可以通过接口函数、链接库或系统调用等方式来实现。这种方法可以灵活地使用其他编程语言的功能,提高程序的功能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值