文章目录

  • 一、可选方案
  • 二、验证结果分析
  • 1,通过JSON-RPC的方式
  • 2,通过安装Linux虚拟机,将C#代码编译成.so共享库
  • 对C#代码进行编译
  • 三、另一个大方向
  • 通过QEMU安装可以在AMD64 windows系统上运行的linux进行编译,这就不涉及交叉编译了
  • 总结



一、可选方案

如何在flutter中调用C#,网上能查到的方案大概有以下几种:

  • 通过RPC,flutter运行时启动另外一个线程,线程中运行C#的RPC服务,通过和RPC服务的交互实现flutter调用C#,但是这种方式只适合与windows,因为C#打包还是生成了dll文件,不能在android上运行(参阅:https://github.com/YehudaKremer/FlutterCsharpRpc?tab=readme-ov-file);
  • 通过Mono将C#编译成.so共享库,目前已知,在windows电脑上无法通过Mono将C#编译成.so,除非使用交叉编译,或者在Linux系统上进行编译,主要工作量在C#端;
  • 通过flutter ffi调用C/C++,再通过C/C++调用C#的dll,这种方式最麻烦,所有的接口都需要映射,但是C#端几乎不用改动;

二、验证结果分析

1,通过JSON-RPC的方式

首先,在windows端,flutter可以直接通过ffi调用C/C++打包的dll,如果是C#,可以在C#代码外层添加一层RPC server,通过json进行数据交互,flutter中也是通过JSON-RPC进行交互,flutter启动以后,启动一个单独的process,然后启动C#的RPC server,因为C#的dll可以在windows环境直接运行;但是放到安卓中,android系统是基于linux系统的,不支持dll的运行,不能直接启动C#的RPC server,所以这种方式放弃;

2,通过安装Linux虚拟机,将C#代码编译成.so共享库

搭建VM ware,安装Ubuntu系统,安装.net开发环境,将C#代码复制到编译器中,通过mcs命令将C#代码编译成.so文件,然后将.so文件复制到flutter项目中,
放置.so具体目录:
D:\项目名\build\app\intermediates\merged_native_libs\debug\out\lib\x86
D:\项目名\build\app\intermediates\merged_native_libs\release\out\lib\x86
还需要配置:\android\app\build.gradle

buildTypes {
        release {
            signingConfig signingConfigs.release
            ndk {
             //这里其实我觉可以直接是用"armeabi-v7a",但国内几个大哥之前使用的都是"armeabi"
             abiFilters "armeabi-v7a"
         }
        }
 
        debug {
            signingConfig signingConfigs.debug
            ndk {
                //这里要加上,否则debug包会出问题,后面两个为可选,x86建议加上不然部分模拟器回报错
                abiFilters "armeabi","armeabi-v7a","arm64-v8a", "x86"
            }
        }
    }

以上内容,原文链接:

Android flutter使用Java sdk flutter调用android接口_arm


目前这个报错是因为AMD64架构的机器上安装的虚拟Linux系统打包生成的so文件,直接放到arm架构的android系统上不能执行,必须进行交叉编译;


然后继续研究,是否能在虚拟Linux系统上进行C#的交叉编译,这就涉及到了知识盲区了。

安装 Mono 开发工具包,并确保你已经安装了适用于 ARM 架构的交叉编译器(如 arm-linux-gnueabihf-gcc)。

安装arm-linux-gnueabihf-gcc

sudo apt install arm-linux-gnueabihf-gcc

编译过程:

通过以下命令将c#代码编译成dll文件

mcs -target:library -out:library.dll main.cs

通过以下命令将dll文件编译成so库

mkbundle -o shared_library.so --cross arm-linux-gnueabihf library.dll.so

这里就出现问题了,一直报错:

mkbundle -o shared_library.so --cross /usr/bin/arm-linux-gnueabihf library.dll
From: /usr/bin/arm-linux-gnueabihf
ERROR: The specified SDK path does not exist: /usr/bin/arm-linux-gnueabihf

这个问题尝试了多个方案一直没有解决:
1,重新安装arm-linux-gnueabihf交叉编译器,未解决次报错

sudo apt update
sudo apt upgrade
sudo apt install arm-linux-gnueabihf

2,使用交叉编译器的绝对路径的arm-linux-gnueabihf或者是arm-linux-gnueabihf-gcc给–cross传参,也不能解决次问题;

mkbundle -o shared_library.so --cross /usr/bin/arm-linux-gnueabihf library.dll

//或者
mkbundle -o shared_library.so --cross /usr/bin/arm-linux-gnueabihf-gcc library.dll

// 如果不知道arm-linux-gnueabihf的路径,使用如下命令查找
whereis arm-linux-gnueabihf

左右查找,发现需要重新安装mono

第一种方式是直接通过命令安装

cd /usr/src
sudo wget https://download.mono-project.com/sources/mono/mono-6.12.0.122.tar.xz
tar xvf mono-6.12.0.122.tar.xz

记住wget前要加sudo,否则不能直接往/usr/src下写文件,这种方式每问题,但是很缓慢。

第二种方式:如果想快点下载用梯子在window系统用哪个连接下载就可以,然后拷贝到虚拟机中,再执行第三条解压命令。

下载完解压完毕后,执行编译命令:

cd /usr/src/mono-6.12.0.122
./configure --prefix=/usr
make
sudo make install

运行./configure命令的时候可能会报g++没有安装,使用一下命令进行安装

sudo apt-get install g++

然后继续运行make命令对mono进行编译。完毕以后就可以对C#代码进行重新编译了,但是还在报相同的错:

mkbundle -o shared_library.so --cross /usr/bin/arm-linux-gnueabihf library.dll
From: /usr/bin/arm-linux-gnueabihf
ERROR: The specified SDK path does not exist: /usr/bin/arm-linux-gnueabihf

改成如下命令:第一个路径是monoSDK的路径,但是mono编译完还是找不到mono-2

kbundle -o shared_library.so --cross /usr/include/mono/4.5/mono-2 arm-linux-gnueabihf-gcc library.dll

没招了,交叉编译这块是真不懂,只能继续研究了;

对C#代码进行编译

对C#代码进行编译首先尝试如下命令:

// 首先对c#进行编译,生成dll文件
mcs -target:library -out:library.dll main.cs

// 下边--cross后的第一个参数路径/usr/ 是编译后生成的SDK目录,第二个参数是交叉编译器的路径,要编译的文件是library.dll
mkbundle -o shared_library.so --cross /usr/include/mono/4.5/mono-2 arm-linux-gnueabihf-gcc library.dll

三、另一个大方向

通过QEMU安装可以在AMD64 windows系统上运行的linux进行编译,这就不涉及交叉编译了

这种方式原理上是可以实现的,QEMU的安装请参阅另一篇文章

总结

叨叨了半天,最终还是么有搞定,是不是有些失望,还在继续努力,主要是想编译成android上可以用的so库,如果是windows上就好解决多了,[参阅](https://github.com/YehudaKremer/FlutterCsharpRpc) 时间有限,后期继续研究。