我正在尝试使用FFI的“不透明指针”样式,其中C#(Unity)代码只将我的Rust类型视为IntPtr,它必须传递给各种Rust函数。但是,一旦我引用的函数引用枚举,我就会得到EntryPointNotFound异常。
不的两个函数引用枚举工作正常,但该函数无法明显绑定并抛出一个EntryPointNotFoundException。我在dynlib(bundle)文件中包含了符号,以表明符号在文件中。
我在Rust中的extern "C"
中没有使用“C”,在C#中使用CallingConvention=CDecl
和CallingConvention=StdCall
但是没有改变这种情况 - int和int指针函数将运行(它们各自的打印功能确实打印),但枚举指针函数只抛出EntryPointNotFoundException并且永远不会打印“enum pointer fine”。
pub enum TestEnum{Test(i32)}
#[no_mangle]
pub extern "C" fn ptr_test(arg: *mut i32) {}
#[no_mangle]
pub extern "C" fn int_test(arg: i32) {}
#[no_mangle]
pub extern "C" fn consume_ptr(arg: *mut TestEnum) {}
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;
public class RustTest : MonoBehaviour {
[DllImport("libptr_test")]
private static extern void ptr_test(IntPtr x);
[DllImport("libptr_test")]
private static extern void int_test(int x);
[DllImport("libptr_test")]
private static extern void consume_ptr (IntPtr x);
// Use this for initialization
void Start () {
print ("Hello World!");
ptr_test (new IntPtr (0));
print ("pointer fine");
int_test (0);
print ("int fine");
consume_ptr (new IntPtr (0));
print ("enum pointer fine");
print ("Done!");
}
// Update is called once per frame
void Update () {
}
}
...
00000000000009c0 T _consume_ptr
0000000000000990 T _int_test
0000000000000960 T _ptr_test
...
答案 0 :(得分:3)
我无法重现您的行为。这是我的Rust来源:
pub enum TestEnum{Test(i32)}
#[no_mangle]
pub extern "C" fn consume_ptr(arg: *mut TestEnum) {
println!("{:?}", arg);
}
我用rustc --crate-type=dylib example.rs
然后我将生成的example.dll复制到.NET控制台应用程序中,并使用此P / Invoke签名:
[DllImport("example.dll", EntryPoint = "consume_ptr", CallingConvention = CallingConvention.Cdecl)]
private static extern void consume_ptr(int arg);
static void Main(string[] args)
{
consume_ptr(0);
}
并且0x0
将打印到控制台。我不知道如何从.NET正确创建和生成Rust枚举,但它不会产生“EntryPointNotFoundException”,并通过查看带有Dependency Walker的导出确认它已正确导出。 / p>