c#调用dll里的某个方法,该方法返回值类型是dll里定义的一个类,该如何强转

是这样的,我是利用反射,调用了dll(我把这个dll放在了lib文件夹里)里的某个方法,但这个方法返回值类型是dll中定义的一个类AppInfo,于是我在引用中添加了该d... 是这样的,我是利用反射,调用了dll(我把这个dll放在了lib文件夹里)里的某个方法,但这个方法 返回值类型 是dll中定义的一个类AppInfo,于是我在引用中添加了该dll,using dll名字,现在可以实例化AppInfo这个类了,但用invoke反射调用方法后强转(AppInfo)method.invoke(...)报错,提示无法将[A]AppInfo转换为[B]AppInfo,
[A]处的AppInfo在lib下的dll位置处,[B]处的AppInfo在 “我的源程序” 的Bin/debug/下的dll位置处,如何解决啊
展开
 我来答
CodeBlove
2014-09-30 · TA获得超过3363个赞
知道小有建树答主
回答量:936
采纳率:79%
帮助的人:232万
展开全部

利用反射调用DLL,并使用DLL中的类创建对象,类型必须加全域名。

 

不过你的问题是不是这个原因需要排查,另外,你可以为你的类定义一个接口,返回后强制转换为接口试试。

 

我给你个,给定域名空间和DLL文件路径及文件名、类名,动态创建对象的构造类。看看有没有帮助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;
namespace ICom.CommonLib
{
    /// <summary>
    /// 使用应用程序域动态方式创建对象。
    /// </summary>
    public class ObjectConstructor : IDisposable,IObjectConstructor
    {
        #region 内部对象
        AppDomain _Domain = null;
        Hashtable _DomainHash = new Hashtable();
        RemoteAssemblyFactory _RAF = null;
        string _DomainName;
        bool _Disposed;
        #endregion
        #region 构造函数
        /// <summary>
        /// 析构函数,释放内部对象。
        /// </summary>
        ~ObjectConstructor()
        {
            Dispose(false);
        }
        #endregion
        #region +属性
        #region 状态消息
        string _Message = "";
        /// <summary>
        /// 读取状态消息。
        /// </summary>
        public string Message
        {
            get { return _Message; }
        }
        #endregion
        #endregion
        #region 方法
        /// <summary>
        /// 创建应用程序域。
        /// <param name="DomainName">应用域名。</param>
        /// </summary>
        /// <returns>成功标志。</returns>
        public bool CreateDomain(string DomainName)
        {
            if (!CreateRemoteAssemblyFactory(DomainName)) return false;
            _DomainName = DomainName;
            return true;
        }
        /// <summary>
        /// 动态创建对象。
        /// <param name="DllFile">库文件路径和文件名。</param>
        /// <param name="ObjectFullName">对象命名空间名及对象名称。</param>
        /// </summary>
        /// <returns>动态创建的对象或者空值(NULL)。</returns>
        public object CreateObject(string DllFile,string ObjectFullName)
        {
            Assembly asm;
            Type type;
            object obj = null; ;
            if (_RAF != null)
            {
                try
                {
                    asm = _RAF.Create(DllFile);
                    type = asm.GetType(ObjectFullName);
                    obj = Activator.CreateInstance(type);
                }
                catch (Exception e)
                {
                    _Message = e.Message;
                }
            }
            return obj;
        }
        #region 释放对象
        /// <summary>
        /// 释放托管资源。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// 释放所有资源。
        /// </summary>
        /// <param name="disposing">Dispose调用标志。</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_Disposed)
            {
                if (disposing)
                {
                    if (_RAF != null) _RAF.Dispose();
                    if (_DomainHash.ContainsKey(_DomainName))
                    {
                        _Domain = (AppDomain)_DomainHash[_DomainName];
                        AppDomain.Unload(_Domain);
                        _DomainHash.Remove(_DomainName);
                    }
                }
                //非托管
                _Disposed = true;
            }
        }
        #endregion
        #endregion
        #region 局部函数
        private bool CreateRemoteAssemblyFactory(string dmn)
        {
            AppDomainSetup setup = new AppDomainSetup();
            string thisdll, nspc = this.GetType().Namespace;
            setup.ShadowCopyFiles = "true";
            _Domain = AppDomain.CreateDomain(dmn, null, setup);
            _DomainHash.Add(dmn, _Domain);
            thisdll = Assembly.GetExecutingAssembly().Location;
            try
            {
                _RAF = (RemoteAssemblyFactory)_Domain.CreateInstanceFromAndUnwrap(thisdll, "ICom.CommonLib.RemoteAssemblyFactory");
                return true;
            }
            catch (Exception e)
            {
                _Message = e.Message;
            }
            return false;
        }
        #endregion
    }
    /// <summary>
    /// 远程程序集工厂。
    /// </summary>
    public class RemoteAssemblyFactory : MarshalByRefObject, IDisposable
    {
        Assembly _ASM = null;
        bool _Disposed;
        /// <summary>
        /// 析构函数,释放内部对象。
        /// </summary>
        ~RemoteAssemblyFactory()
        {
            Dispose(false);
        }
        /// <summary>
        /// 创建远程程序集。
        /// </summary>
        /// <param name="dllFile">程序集所在DLL文件的路径和文件名。</param>
        /// <returns>程序集对象或空值(NULL)。</returns>
        public Assembly Create(string dllFile)
        {
            try
            {
                _ASM = Assembly.LoadFrom(dllFile);
                return _ASM;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// 释放托管资源。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// 释放资源。
        /// </summary>
        /// <param name="disposing">Dispose调用标志。</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_Disposed)
            {
                if (disposing)
                {
                    _ASM = null;
                }
                //非托管
                _Disposed = true;
            }
        }
    }
}
makosharp
2014-10-08 · TA获得超过676个赞
知道小有建树答主
回答量:188
采纳率:100%
帮助的人:265万
展开全部

这是个很常见的同结构同名类跨域互转问题。


假定A.Dll中有一个public ANameSpace.AppInfo SomeMethod()方法。

如果AppInfo在A.Dll中定义,同名同结构的AppInfo类在B.Dll中也有定义,那么不管你是使用using A还是反射得到一个A中AppInfo类型的值,都不允许在B中使用(BNameSpace.AppInfo)SomeMethod()进行类型转换,即使我们知道两个AppInfo结构是完全一样的。


取决于应用环境,一般会有以下几种处理方式。

  1. 如果A.Dll允许被using。不存在上述问题,直接在B中使用A中定义的AppInfo。

  2. 如果A.Dll不允许被using,但允许被有限度的修改。常见的解决方法,让AppInfo实现接口、或者将A中AppInfo更改为框架内置的数据类型比如List<>等、让A中AppInfo支持序列化/反序列化(XmlSerialization最佳/BinarySerialization亦可)都可以满足大部分需要,同时尽可能避免B的更改。

  3. 如果A.Dll不允许被using,也不允许被修改。必须通过反射实现类型转换。标准做法是在B中自写TypeConverter以提供object向B中AppInfo转换的功能(当然这里的object的实际类型是A中的AppInfo)。该类型转换器应能够通过反射获取必要的值并填充至新AppInfo对象的对应字段。以上操作本质上就是对象的浅表克隆。当然,偷懒的话在B中AppInfo类上多重载一个构造以从object获取初始值也行,但是依然是要依靠反射去访问你需要的属性并填充。


此外,类似问题我在另一处已作答,仅供参考:

http://zhidao.baidu.com/link?url=SbQVATgclcsoPfN9apsCrHKKIEGFysW0x6_-zda-J2PbUNaGtQfem8hLejn5ct_3iDQYqr7QdUQ3xrRjvxvI9HdGK932REhMPQ-paCCXTdO

本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友cfe4d0f
2014-10-06 · TA获得超过1502个赞
知道小有建树答主
回答量:937
采纳率:100%
帮助的人:848万
展开全部
首先 你确定返回类型是你找到的dll中的类,而不是同名的其他来源类?
如果以上已经确认但是依然出现问题
你可以继续用反射来访问返回的变量 不需要转换类型也能继续使用
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友9fb0d305e
2014-09-29 · TA获得超过193个赞
知道小有建树答主
回答量:292
采纳率:0%
帮助的人:193万
展开全部
添加引用,using 空间名后就可以直接:AppInfo info=DLL.Method() 还用反射?
追问
我用的反射,别说其他的,谢谢
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
旁笑槐NH
2014-10-03 · TA获得超过2545个赞
知道大有可为答主
回答量:2686
采纳率:0%
帮助的人:2852万
展开全部
这是因为这两个DLL的版本不一样 你可以检查下它们的MD5是不是一样
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 2条折叠回答
收起 更多回答(4)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式