You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#反射调用DLL方法传递结构体参数报错的解决办法

反射调用DLL传递结构体时类型转换异常的解决

问题场景

反射动态调用DLL时,传递结构体参数触发如下异常:

System.ArgumentException: Object of type 'MRaport' cannot be converted to type 'MRaport'.

本地代码:

public struct MRaport
{
    public int rapId;
    public string rapName;
    public string Level;
}

private void CreateRap()
{
    Assembly assembly = Assembly.LoadFrom(@"path\RapLibrary.dll");
    Type myLibraryType = assembly.GetType("XReport");
    object myLibraryInstance = Activator.CreateInstance(myLibraryType);

    bool x = true;
    MRaport mr = new MRaport { rapId = 1, rapName = "MxFolder", Level = "Red" };
    MethodInfo methodInfo = myLibraryType.GetMethod("fillRaport");
    object[] parameters = new object[] { x, mr };

    try
    {
        string result = (string)methodInfo.Invoke(myLibraryInstance, parameters);
        MessageBox.Show(result);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

类库(RapLibrary.dll)代码:

public struct MRaport
{
    public int rapId;
    public string rapName;
    public string Level;
}

public class XReport
{
    public string fillRaport(bool x, MRaport mr)
    {
        if (x)
        {
            return mr.rapName;
        }
        else
        {
            return mr.Level;
        }
    }
}

问题原因

本地代码和DLL中分别定义了同名同结构但分属不同程序集的MRaport结构体,CLR会将它们视为完全独立的类型,因此传递参数时触发类型不匹配异常。

解决方法

方法1:共享结构体定义(推荐)

将MRaport结构体抽离到独立的共享类库(如SharedModels.dll),让本地项目和RapLibrary.dll项目同时引用该类库。这样两边使用的是同一个程序集下的MRaport类型,参数传递时不会出现类型冲突。

修改后本地代码无需重复定义结构体:

// 直接引用SharedModels.dll中的MRaport类型
private void CreateRap()
{
    Assembly assembly = Assembly.LoadFrom(@"path\RapLibrary.dll");
    Type myLibraryType = assembly.GetType("XReport");
    object myLibraryInstance = Activator.CreateInstance(myLibraryType);

    bool x = true;
    MRaport mr = new MRaport { rapId = 1, rapName = "MxFolder", Level = "Red" };
    MethodInfo methodInfo = myLibraryType.GetMethod("fillRaport");
    object[] parameters = new object[] { x, mr };

    try
    {
        string result = (string)methodInfo.Invoke(myLibraryInstance, parameters);
        MessageBox.Show(result);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

RapLibrary.dll代码同样改为引用共享类库的MRaport:

// 引用SharedModels.dll中的MRaport类型
public class XReport
{
    public string fillRaport(bool x, MRaport mr)
    {
        if (x)
        {
            return mr.rapName;
        }
        else
        {
            return mr.Level;
        }
    }
}

方法2:动态创建DLL中的结构体实例

如果无法使用共享类库,可以从加载的DLL中获取MRaport类型,动态创建实例并赋值后再传递:

private void CreateRap()
{
    Assembly assembly = Assembly.LoadFrom(@"path\RapLibrary.dll");
    Type myLibraryType = assembly.GetType("XReport");
    object myLibraryInstance = Activator.CreateInstance(myLibraryType);
    // 获取DLL内部的MRaport类型
    Type raportType = assembly.GetType("MRaport");

    bool x = true;
    // 动态创建DLL中MRaport的实例
    object mrInstance = Activator.CreateInstance(raportType);
    // 给结构体字段赋值
    raportType.GetField("rapId").SetValue(mrInstance, 1);
    raportType.GetField("rapName").SetValue(mrInstance, "MxFolder");
    raportType.GetField("Level").SetValue(mrInstance, "Red");

    MethodInfo methodInfo = myLibraryType.GetMethod("fillRaport");
    object[] parameters = new object[] { x, mrInstance };

    try
    {
        string result = (string)methodInfo.Invoke(myLibraryInstance, parameters);
        MessageBox.Show(result);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

内容的提问来源于stack exchange,提问作者Wals

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:32:48