我正在尝试使用 FFI 的“不透明指针”样式,其中 C#(Unity)代码仅将我的 Rust 类型视为必须传递给各种 Rust 函数的 IntPtr。但是,一旦我引用的函数引用枚举,我就会收到 EntryPointNotFound 异常。
不引用枚举的两个函数工作正常,但引用枚举的函数显然无法绑定并抛出 EntryPointNotFoundException。我已将符号包含在 dynlib(捆绑包)文件中,以表明该符号位于文件中。
我尝试过在 Rust 中的extern "C"
中不使用“C”,以及 C# 中的
CallingConvention=CDecl
和
CallingConvention=StdCall
中的“C”,但这并没有改变情况 - int 和 int 指针函数将运行(它们各自的打印函数确实) print),但枚举指针函数只是抛出 EntryPointNotFoundException 并且永远不会打印“枚举指针罚款”。ptr_test.rs
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) {}
RustTest.cs
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 () {
}
}
nm -gU 雕刻-unity/carved/Assets/libptr_test.bundle
...
00000000000009c0 T _consume_ptr
0000000000000990 T _int_test
0000000000000960 T _ptr_test
...
pub enum TestEnum{Test(i32)}
#[no_mangle]
pub extern "C" fn consume_ptr(arg: *mut TestEnum) {
println!("{:?}", arg);
}
我用
rustc --crate-type=dylib example.rs
[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 查看导出来确认它已正确导出。
EntryPointNotFoundException
。我有一个名为
myproject
的 Rust 项目,导出了
myproject.dll
并创建了一个名为
MyProject
的 C# 绑定项目,该项目导入了 DLL。然而我的符号却从未在其中被发现。原因只是 C# 代码 (
MyProject.dll
) 生成的程序集与输出目录中的 Rust 库
myproject.dll
的名称冲突。只需重命名其中一个项目就解决了我的问题。我花了一段时间才弄清楚,希望这可以帮助人们避免同样的错误。