【发布时间】:2016-04-10 11:57:29
【问题描述】:
大家好,我在 unity3d pro 上遇到了一些问题,也许使用 DLL 原生插件的人可以阐明我做错了什么。
首先,我将解释我的目标是什么。我有一个来自 Siemens PLCSim 软件的 COM 对象,我已经让它在 Visual Studio 中正常工作。下面是测试代码。
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public S7PROSIMLib.S7ProSim PLCSimConn = new S7PROSIMLib.S7ProSim();
public Form1()
{
InitializeComponent();
}
private void button_Connect_Click(object sender, EventArgs e)
{
PLCSimConn.Connect();
label_CPUState.Text = PLCSimConn.GetState();
label_ScanMode.Text = PLCSimConn.GetScanMode().ToString();
}
}
}
我创建了一个 unity3d 项目来测试它。我将 dll 导入到我的资产中,并且能够从我的 c# 脚本调用 S7PROSIMLib 的方法和实例。 COM Api 在这里,https://cache.industry.siemens.com/dl/files/855/1139855/att_29424/v1/S7WSPSCB.pdf
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using S7PROSIMLib;
public class TestNative : MonoBehaviour {
public S7ProSimClass ps;
// Use this for initialization
void Start () {
ps = new S7ProSimClass ();
ps.Connect ();
Debug.Log (ps.GetState());
}
}
现在在运行时我得到以下信息:
COM异常
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR (Int32 errorCode) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs:1031)
System.__ComObject.Initialize (System.Type t) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/__ComObject.cs:103)
(wrapper remoting-invoke-with-check) System.__ComObject:Initialize (System.Type)
Mono.Interop.ComInteropProxy.CreateProxy (System.Type t) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/Mono.Interop/ComInteropProxy.cs:108)
System.Runtime.Remoting.RemotingServices.CreateClientProxyForComInterop (System.Type type) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:588)
System.Runtime.Remoting.Activation.ActivationServices.CreateProxyForType (System.Type type) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Remoting.Activation/ActivationServices.cs:234)
TestNative.Start () (at Assets/Scripts/TestNative.cs:13)
我看过unity3d插件教程https://www.youtube.com/watch?v=DfRYLwG1Bug,它不调用第三方DLL。
我已阅读以下内容:https://msdn.microsoft.com/en-us/library/ms973872.aspx,其中包含很多关于非托管和托管 DLL 的有用信息。
基于以上链接中的以下 sn-p:
调用 COM API 有两种方法可以从托管代码调用 COM 组件:通过 COM 互操作(适用于所有托管语言)或通过 C++ 互操作(适用于 C++)。 对于调用 OLE 自动化兼容的 COM 组件,建议使用 COM 互操作。 CLR 将负责 COM 组件的激活和参数封送处理。
对于基于接口定义语言 (IDL) 调用 COM 组件,建议使用 C++ 互操作。 C++ 层可以非常薄,其余的托管代码可以用任何托管语言编写。 COM 互操作依赖于来自类型库的信息来进行正确的互操作调用,但类型库通常不包含 IDL 文件中存在的所有信息。使用 C++ 互操作通过允许直接访问这些 COM API 解决了这个问题。
我相信我已经完成了上面统一 c# 脚本中显示的 COM 互操作。那没有用。我的另一个选择是通过 C++ 互操作,但我没有在网上找到任何示例。大多数示例都很简单,无需调用 COM 对象或任何其他第三方 DLL。如果有人能以正确的方式指导我,我将不胜感激。基本上它归结为最好的方法是什么,而对方法的重新编写最少?谢谢!
Edit1:我在 youtube 上观看了有人让它工作的视频,但我无法得到他的回复。至少我知道它应该在 unity3d 上工作。 https://www.youtube.com/watch?v=EGFMjUJN7ZU
Edit2:Unity3d - Failed to load 'Assets/Plugins/QCARWrapper.dll' 将按照这篇文章的建议尝试使用 32 位编辑器。
【问题讨论】:
-
@FᴀʀʜᴀɴAɴᴀᴍ 我也在这里读到了这个msdn.microsoft.com/en-us/library/…我可能误解了文献。那么这是否意味着我需要创建一个 DLL 来调用我的第三方 DLL 中的方法签名?你知道网上有什么好的例子吗?
-
一点,考虑无处不在的 Prime31 插件
-
@joeblow 这些插件都没有处理我正在做的事情。不过感谢您的评论。
-
对,对不起,我只看了你的问题。在过去,prime31 在一个包中有一些出色的 DLL 示例代码,但现在已经不存在了。如果您还没有看过它,这是否有帮助ericeastwood.com/blog/17/…
-
是的,我也看过他的博客。而且他也不使用第三方dll。他只是制作了一些功能,并构建了一个dll。然后他使用命名空间从一个 c 语言脚本中调用这些方法。