嗨,大家好,我在unity3d pro上遇到了一些问题,也许有人在使用DLL本机插件时可以了解我做错了什么。从Unity3d调用本机DLL的最佳方式是什么?
开始我会解释我的目标是什么。我有一个来自西门子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());
}
}
现在在运行时,我得到如下:
收到COMException
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上有很多很好的信息。
基于从上面的链接下面的代码片段:
调用COM API的 有两种方法可以从托管代码调用COM组件:通过COM互操作(在所有管理语言),或通过C++互操作(可用C++提供)。 对于调用OLE自动化兼容的COM组件,建议使用COM互操作。 CLR将负责COM组件激活和参数封送。
对于基于接口定义语言(IDL)调用COM组件,建议使用C++ interop。 C++层可以非常简洁,其余的托管代码可以用任何托管语言编写。 COM互操作依赖类型库中的信息来进行正确的互操作调用,但类型库通常不包含IDL文件中存在的所有信息。使用C++ interop通过允许直接访问这些COM API来解决这个问题。
我相信我已经在上面的unity c#脚本中显示了COM interop。这并不奏效。我的其他选择是通过C++互操作,但我还没有找到任何在线的例子。大多数示例都很简单,无需调用COM对象或任何其他第三方DLL。如果有人能以正确的方式指导我,我将不胜感激。基本上归结为什么是最好的方式去做这件事,用最少的方法重写?谢谢!
编辑1:我在YouTube上观看了这段视频,看看是否有人开始工作,但我一直没有得到他的回复。至少我知道它应该在unity3d上工作。 https://www.youtube.com/watch?v=EGFMjUJN7ZU
编辑2:Unity3d - Failed to load 'Assets/Plugins/QCARWrapper.dll'将尝试使用32位编辑器,因为这篇文章建议。
@FᴀʀʜᴀɴAɴᴀᴍ我也看了这个位置https://msdn.microsoft.com/en-us/library/42b9ea93%28v=vs.110%29.aspx ?cs-save-lang = 1&cs-lang = csharp#code-snippet-1我可能误解了文献。那么这是否意味着我需要创建一个DLL来调用我的第三方DLL中的方法签名?你知道任何在线的好例子吗? – kodaman
一点,考虑无处不在的Prime31插件 – Fattie
@joeblow这些插件都不涉及我正在做的事情。尽管感谢您的评论。 – kodaman