编程语言
首页 > 编程语言> > 在Enum(EntryPointNotFound)上使用IntPtr从C#调用Rust失败

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

作者:互联网

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

这两个不引用枚举的函数都可以正常工作,但是确实不能绑定并抛出EntryPointNotFoundException的函数.我已将符号包括在dynlib(捆绑)文件中,以表明该符号在文件中.

我试过在Rust中的外部“ C”中没有“ C”,并且在C#中没有CallingConvention = CDecl和CallingConvention = StdCall,但这并没有改变情况-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雕刻单位/雕刻/资产/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中正确创建和封送Rust枚举,但是它不会产生“ EntryPointNotFoundException”,并且已经通过查看具有Dependency Walker的导出来确认已正确导出.

标签:rust,ffi,c
来源: https://codeday.me/bug/20191119/2032621.html