从 C# 使用 COM 库到 rust

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

问题

我想将我的项目从 C# 重写为 Rust。 但我陷入了分段错误的情况。 我想我误解了一些东西,或者遇到了板条箱限制,希望得到一些帮助。

Rust 代码

use windows::core::{GUID, HRESULT, IUnknown, IUnknown_Vtbl, interface};
use windows::Win32::System::Com::{
    COINIT_APARTMENTTHREADED, 
    CLSCTX_ALL,
    CoInitializeEx,
    CoCreateInstance};

// define interface
#[interface("288EFDEC-3CF0-4F6C-8473-4E4CD47A93C7")]
unsafe trait Inhicshisx: IUnknown {
    fn VPNGetRandomX(&self) -> HRESULT;
}

fn run() -> Result<(), anyhow::Error> {
    unsafe {
        // 2F5AECD5-B5CD-41E1-8265-E2F6AA4548CB
        const CLSID: GUID = GUID {
            data1: 0x2F5AECD5,
            data2: 0xB5CD,
            data3: 0x41E1,
            data4: [0x82, 0x65, 0xE2, 0xF6, 0xAA, 0x45, 0x48, 0xCB],
        };
        
        // initialize runtime
        CoInitializeEx(Some(ptr::null_mut() as *mut c_void), COINIT_APARTMENTTHREADED)?;
        
        // create COM object
        let hisx: Inhicshisx = CoCreateInstance(&CLSID, None, CLSCTX_ALL)?;
        
        // call object function
        let value = hisx.VPNGetRandomX();
    }
    
    Ok(())
}

C# 部分

using CSHISXLib;
string MyStr0;
CSHISXLib.Inhicshisx CSHISXLibObj = new CSHISXLib.nhicshisx();
MyStr0 = CSHISXLibObj.VPNGetRandomX();
Console.WriteLine(MyStr0);
  • 它有效。

更新信息

根据@IInspectable帮助,我可以通过oleview.exe工具生成界面。

  • 生成的界面
[
  odl,
  uuid(288EFDEC-3CF0-4F6C-8473-4E4CD47A93C7),
  helpstring("Inhicshisx Interface"),
  dual,
  oleautomation
]
interface Inhicshisx : IDispatch {
    [id(0x00000001), helpstring("method VPNGetRandomX")]
    HRESULT VPNGetRandomX([out, retval] BSTR* strRandom);
    [id(0x00000002), helpstring("method VPNH_SignX")]
    HRESULT VPNH_SignX(
                    [in] BSTR strRandom, 
                    [in, optional, defaultvalue("")] BSTR strCardType, 
                    [in, optional, defaultvalue("")] BSTR strServiceType, 
                    [out, retval] BSTR* strRet);
}
  • Rust 代码更改
use windows::core::BSTR;

#[interface("288EFDEC-3CF0-4F6C-8473-4E4CD47A93C7")]
unsafe trait Inhicshisx: IDispatch {
    fn VPNGetRandomX(&self) -> BSTR;
    fn VPNH_SignX(&self, *mut BSTR, *mut BSTR, *mut BSTR) -> BSTR;
}

但是还是导致分段错误,希望大家指教🙏

rust com windows-rs
2个回答
1
投票

感谢@IInspectable 的建议。

接口错误导致的分段错误

找到COM接口

您可以使用oleview来显示COM库界面。就我而言,界面是这样的。

interface Inhicshisx : IDispatch {
    [id(0x00000001), helpstring("method VPNGetRandomX")]
    HRESULT VPNGetRandomX([out, retval] BSTR* strRandom);
    [id(0x00000002), helpstring("method VPNH_SignX")]
    HRESULT VPNH_SignX(
                    [in] BSTR strRandom, 
                    [in, optional, defaultvalue("")] BSTR strCardType, 
                    [in, optional, defaultvalue("")] BSTR strServiceType, 
                    [out, retval] BSTR* strRet);
}

在 Rust 中声明接口

#[interface("288EFDEC-3CF0-4F6C-8473-4E4CD47A93C7")]
unsafe trait Inhicshisx: IDispatch {
    fn VPNGetRandomX(&self, random: *mut BSTR) -> HRESULT;
    fn VPNH_SignX(&self, random: BSTR, card_type: BSTR, service_type: BSTR, sign: *mut BSTR) -> HRESULT;
}

0
投票

您可以与我分享如何在 Rust 中使用 COM 接口的演示吗?谢谢。

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