指定文件打包:kotlinc-native 需要先安装
kotlin-native-prebuilt-windows-x86_64-2.0.0.zip
kotlinc-native -p dynamic -o example Example.k
kotlin代码:
@OptIn(ExperimentalNativeApi::class)
@CName("exampleFunction")
fun exampleFunction(name: String, password: String): String {
return "$name - Hello from Kotlin/Native! - $password"
}
@OptIn(ExperimentalNativeApi::class)
@CName("testCallback")
fun testCallback(name: String, password: String, callback : (p : String) -> String) {
callback("$name - $password")
}
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("callbackMethod1")
fun callbackMethod1(t: CPointer<CFunction<() -> CArrayPointer<ByteVar>>>) : String {
return t.reinterpret<CFunction<() -> CArrayPointer<ByteVar>>>().invoke().toKString()
}
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("callbackMethod2")
fun callbackMethod2(t: CPointer<CFunction<(CValues<ByteVar>, CValues<ByteVar>) -> CArrayPointer<ByteVar>>>) : String {
return t.reinterpret<CFunction<(CValues<ByteVar>, CValues<ByteVar>) -> CArrayPointer<ByteVar>>>().invoke(
"zzm".cstr,
"123456".cstr
).toKString()
}
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("getTT1")
fun getTT1(name: String, password: String): TT1 {
return TT1(name, password)
}
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("getTT1Name")
fun getTT1Name(obj: TT1): String {
return obj.name
}
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("getTTm1")
fun getTTm1(obj: TT1): String {
return obj.m1()
}
class TT1(
val name: String,
val password: String
){
fun m1() : String{
return "$name -- $password"
}
}
C#代码:
const string DllName = "C:\\git-code\\AIOT_aqara_sys\\build\\bin\\native\\debugShared\\aqaraSys.dll";
[DllImport(DllName, EntryPoint = "exampleFunction", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr exampleFun(string name, string password);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr callbackMethod1(IntPtr t);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr callbackMethod2(IntPtr t);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getTT1(string name, string password);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getTT1Name(IntPtr t);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getTTm1(IntPtr t);
// 在C#中实现回调函数
public static string MyCallbackFunction1()
{
return "uu";
}
// 在C#中实现回调函数
public static string MyCallbackFunction2(string name, string pwd)
{
return name + "uu" + pwd;
}
// 定义一个 delegate 来匹配你的回调函数的签名
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate string Callback1Delegate();
// 定义一个 delegate 来匹配你的回调函数的签名
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate string Callback2Delegate(string name, string pwd);
static void Main(string[] args)
{
Console.WriteLine("start test...");
// 调用 exampleFunction 函数
IntPtr resultPtr = exampleFun("name", "password");
string result = Marshal.PtrToStringAnsi(resultPtr);
Console.WriteLine("exampleFunction:" + result);
// 创建一个 delegate 实例
Callback1Delegate c1 = MyCallbackFunction1;
IntPtr r1 = callbackMethod1(Marshal.GetFunctionPointerForDelegate(c1));
string result1 = Marshal.PtrToStringAnsi(r1);
Console.WriteLine("callbackMethod:" + result1);
// 创建一个 delegate 实例
Callback2Delegate c2 = MyCallbackFunction2;
IntPtr r2 = callbackMethod2(Marshal.GetFunctionPointerForDelegate(c2));
string result2 = Marshal.PtrToStringAnsi(r2);
Console.WriteLine("callbackMethod1:" + result2);
// 调用 exampleFunction 函数
IntPtr tt1Ptr = getTT1("namexx", "password");
IntPtr tt1NamePtr = getTT1Name(tt1Ptr);
string tt1Name = Marshal.PtrToStringAnsi(tt1NamePtr);
Console.WriteLine("getTT1Name:" + tt1Name);
IntPtr tt1m1Ptr = getTTm1(tt1Ptr);
string tt1m1 = Marshal.PtrToStringAnsi(tt1m1Ptr);
Console.WriteLine("getTT1Name:" + tt1m1);
Console.WriteLine("end test...");
}