调用c#程序集dll学习
c#生成的dll不是c++那种动态库而是程序集, 调用方式不一样
首先, 先用c#创建一个dll, 命名为demodll , 创建三个函数,
第一个 getg 是直接返回一个固定数值12345,
第二个 getv 有一个参数, 然后返回这个参数值,
第三个 swap 包含两个参数, 功能是交换这两个数值, 然后原路返回给这两个参数自己
c#代码如下:
namespace demodll
{
public class Class1
{
public static bool swap(ref int a,ref int b)
{
a = a + b;
b = a - b;
a = a - b;
return true;
}
public static int getv(int a)
{
return a;
}
public static int getg()
{
return 12345;
}
}
}编译好的dll如下:
下面在aardio中调用试试:
import console
console.open()
//调用C#程序集
import dotNet;
var appDomain = dotNet.clr().createAppDomain();
//加载应用程序目录下的程序集
var Demodll = appDomain.loadFile("\res\demodll.dll");
//声明接口
var class1 = Demodll.new("Class1")
//调用固定返回值函数
console.log( class1.getg() )
//调用返回参数值函数
console.log( class1.getv(6787) )
以上两个函数均能成功调用.
第三个参数, 因为参数是引用ref方式, 那么普通的方式肯定不行
var a =12;
var b =34;
console.log("原始顺序:",a,b);
console.log( class1.swap(a,b) );
console.log("交互后:",a,b);
虽然提示true成功了 , 但是并没有改变顺序, 这里既然是引用 , 那么应该需要对参数进行处理下, 我试了下topointer / raw.topointer / raw.struct 都不行.......
有谁知道怎么处理的, 请指教下
c#与aardio进行数组交互
关于参数类型问题:
普通 C#函数不支持 COM接口的参数类型自动转换,如果默认类型转换与 C# 函数的参数类型不一致,可以使用 com.Variant(v,3/*_VT_I4*/) 或者com.SafeArray(3/*_VT_I4*/,12,34,56)这种方式显示的指定调用参数的类型。也可以使用 aardio 新版提供的函数 com.int8,com.int32,com.double …… 等,这些函数可以用于数值也可以用于数组,例如 com.int32({1,2,3}) 可以兼容 C# 的 System.Int32 数组。
这里需要注意一点: aardio中table表, 如果直接传递给c#参数, 是会被默认转换为double[]类型, 如果是其他类型数据, 那么可以利用上面提到的方式来定义
这时候我把c#的代码改下:
public static int[] test( double[] a, double[] b)
{
int x = (int)a[0] + 33;
int y = (int)a[1] + 55;
int z = (int)b[0] + 77;
int u = (int)b[1] + 100;
return new int[4] { x,y,z,u };
}编译为dll之后, 在aardio中调用
console.dump( class1.test({11,22}, {33,44}) );
可以了.
登录后方可回帖


目前有两种方案 :
用c#重新封装下那个函数, 把ref或out关键字的输出参数展开
这里也有两个方案:
a, 类里定义多个全局变量, 把ref参数用全局传递出来
b, 用数组(int[])包装下, 给return返回出来
用dnspy查看dll中源码, 直接修改里面函数返回值 , 修改方法参考1
这里还是以上面的dll为例, 假如我把c#的swap函数代码改如下:
public static int[] swap(int x,int y) { return new int[2] { y,x}; }aardio调用如下:
var a =12; var b =34; console.log("原始顺序:",a,b); console.dump( class1.swap(a,b) );