Marshal error while using an external DLL, can anyone provide pointers or wrongdoing?


I am an automation engineer and I would like to build some troubleshooting scenarios in unity for my coworkers. I came accross a DLL Com object (on windows) Interop.S7PROSIMLib which lets you call methods and read/write in C# to the PLCSim which is great because Siemens PLC Step7 is great to write automation programs. I tested with Visual Studio and it works great.

And this is the code that calls those methods, the reference to the DLL is within the solution explorer in visual studio and thus no need to use using.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
    public partial class Form1 : Form
        public S7PROSIMLib.S7ProSim PLCSimConn = new S7PROSIMLib.S7ProSim();

        public Form1()

        private void button_Connect_Click(object sender, EventArgs e)
            label_CPUState.Text = PLCSimConn.GetState();
            label_ScanMode.Text = PLCSimConn.GetScanMode().ToString();

And in a c sharp script in unity I have this:

using UnityEngine;
using System.Collections;
using S7PROSIMLib;

public class NewBehaviourScript : MonoBehaviour {

    private S7PROSIMLib.S7ProSimClass ps;
    // Use this for initialization
    void Start () {

        ps = new S7PROSIMLib.S7ProSimClass();

I cannot remember how did the DLL became Interop the original name is S7PROSIMLib, I imagine after I dragged and dropped to the assets/plugins folder. After that it was referenced in visual studio as interop.XXX and I was no longer getting the console error in unity of missing reference or using XXX in script.

I got excited when no more console errors where showing. I ran, and then I received a COMException which I have no clue where to fix or even where to begin. This is the error I get in unity something to do with Marshal.

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)
NewBehaviourScript.Start () (at Assets/Scripts/NewBehaviourScript.cs:11)

Can anyone that has experience with this error give me some pointers. Maybe this is not doable. And this is a link to the API for S7ProSim Documentation

Side note: I went through dozens of posts, and links online for using DLL but most of the links are user created DLL’s.

Thanks for your help.

For anyone that might need help with this. Siemens PLCSim COM type library only works with 32bit Unity Editor.

The solution was actually quite easy after lots of trial and error, and many more reading through the forums and what not. I used tlbimp.exe to generate a type library DLL, then I placed that into the assets/plugins folder also note on unity3d editor properties that the new DLL is treated as managed code. Note that this particular DLL doesn’t work on 64bit Unity Editor and it threw a COMException. However the new type library DLL works fine in 32bit Unity Editor, I imagine that somewhere in the DLL there is an instruction specifying to work only in 32bit.

I documented everything on a repository here GitHub - TheFern2/myS7ProSimLib: Imported S7PROSimLib type library. To connect unity3D with Siemens PLCSim using COM Interop. I also placed the managed DLL for future use so you don’t go to the trouble I went.

Below is a sample code:

using UnityEngine;
using myS7ProSimLib;

public class TestNative : MonoBehaviour {

    * Used tlbimp.exe to generate library DLL
    * place new generated DLL on assets/plugins
    * also note that the DLL is treated as managed code
    public S7ProSimClass ps;
    public bool input_0_0;

    void Start () {
        ps = new S7ProSimClass();

        print("State " + ps.GetState());

        // Here we pass the ref as an obj, since WriteInputPoint method
        // can take bit, word, dwords, as addresses ref obj can take the
        // for of bool, int, float, etc.
        object refInput0_0 = input_0_0;
        ps.WriteInputPoint(0, 0, ref refInput0_0);

I had this issue when using coreScanner COM from zebra scanner
currently I stuck dont know what to do.

Any one can advise what I done wrong?