从Excel VBA加载Rust编写的dll

ruyhziif  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(224)

我正在尝试编写动态库并从Excel使用它。
现在我可以从Excel调用我的函数,但似乎函数的参数传递方式错误。
我的Rust代码如下所示

use std::ffi::{c_char, CString};

use windows::core::{BSTR, PCSTR};
use windows::Win32::System::Com::{SAFEARRAY, VARIANT};
    
use windows::Win32::UI::WindowsAndMessaging::*;
use windows::s;

#[cfg(target_arch="x86_64")]
#[no_mangle]
pub extern "stdcall" fn pass_number(input: u32) -> u32 {
        
        let got = input.to_string();
        
        let c_string = CString::new("{}".replace("{}", &got)).unwrap();
        let ptr_str = CString::as_bytes_with_nul(&c_string);
        unsafe { MessageBoxA(None, PCSTR::from_raw(&(ptr_str[0]) as &u8 as *const u8), s!("pass_number()"), MB_OK); }

        input + 100
    }

和VBA代码来加载dll

Public Declare PtrSafe Function add Lib "PATH_TO_DLL" _
Alias "pass_number" (ByVal num As Long) As Long

Sub test()
    MsgBox add(11)
End Sub

当我从Excel工作表调用add()时,Windows消息框弹出,但got的值总是1,无论我传递给它的参数。如果我执行VBA过程,它会引发运行时错误“28”,堆栈空间不足。
我尝试了不同的调用约定,如Win64、cdecl和参数的不同整数数据类型,但结果总是一样的。
从我可以看到Windows消息的事实,我猜我可以调用Excel的函数,但当参数传递给函数时出错了。
我在64位机器上运行该程序,库是使用cargo build --target x86_64-pc-windows-msvc为这种架构编译的。
有人能告诉我丢失了什么吗?

  • 更多信息

我测试了i32作为pass_number()的输入和输出数据类型,但没有任何变化。
pass_number()在Excel工作表中通过add()调用时以某种方式返回,但返回值始终为'101'。然而,当我将Rust代码最后一行的数字100更改为new value时,返回值更改为new value + 1
这是我的货物toml

[lib]
name="rustlib"
crate-type = ["cdylib"]

[dependencies.windows]
version = "0.48"
features = [
    "Data_Xml_Dom",
    "Win32_Foundation",
    "Win32_System_Com",
    "Win32_System_Ole",
    "Win32_Security",
    "Win32_System_Threading",
    "Win32_UI_WindowsAndMessaging",
    "Win32_System_WindowsProgramming",
    ]
    
[dependencies]
lazy_static = "*"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = {version = "*", features = ["rt-multi-thread"]}
futures="*"
ebdffaop

ebdffaop1#

通过安装32位Excel并创建32位DLL,我可以从Excel中调用DLL中的函数。但是仍然有一个问题,从Excel向dll传递指针类型(字符串,或数组)不能很好地工作。

相关问题