gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 07:59:52 25 4
gpt4 key购买 nike

我正在尝试使用 FFI 的“不透明指针”样式,其中 C# (Unity) 代码仅将我的 Rust 类型视为必须传递给各种 Rust 函数的 IntPtr。但是,只要我引用的函数引用枚举,我就会收到 EntryPointNotFound 异常。

引用枚举的两个函数工作正常,但引用枚举的函数显然无法绑定(bind)并抛出 EntryPointNotFoundException。我已将这些符号包含在 dynlib( bundle )文件中以表明该符号在文件中。

我试过在 Rust 的 extern "C" 中不使用 "C",在 Rust 中尝试不使用 CallingConvention=CDeclCallingConvention=StdCall C# 但这并没有改变这种情况 - int 和 int 指针函数将运行(它们各自的打印函数确实打印),但是枚举指针函数只是抛出 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 carved-unity/carved/Assets/libptr_test.bundle

...
00000000000009c0 T _consume_ptr
0000000000000990 T _int_test
0000000000000960 T _ptr_test
...

最佳答案

我无法重现您的行为。这是我的 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 正确创建和编码(marshal) Rust 枚举,但它不会产生“EntryPointNotFoundException”,并且通过使用 Dependency Walker 查看导出已确认它已正确导出.

关于c# - 在 Enum (EntryPointNotFound) 上使用 IntPtr 从 C# 调用 Rust 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35639380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com