使用 IntPtr 从 C# 调用 Rust 在 Enum 上失败 (EntryPointNotFound)

问题描述 投票:0回答:2

我正在尝试使用 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 ...
    
c# rust ffi
2个回答
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 查看导出来确认它已正确导出。


0
投票
我也一直遇到这个问题

EntryPointNotFoundException

。我有一个名为 
myproject
 的 Rust 项目,导出了 
myproject.dll
 并创建了一个名为 
MyProject
 的 C# 绑定项目,该项目导入了 DLL。然而我的符号却从未在其中被发现。

原因只是 C# 代码 (

MyProject.dll

) 生成的程序集与输出目录中的 Rust 库 
myproject.dll
 的名称冲突。只需重命名其中一个项目就解决了我的问题。我花了一段时间才弄清楚,希望这可以帮助人们避免同样的错误。

© www.soinside.com 2019 - 2024. All rights reserved.