17

When running this program I keep receiving the error: An unhandled exception of type 'System.Security.SecurityException' occured Additional Information: ECall methods must be packaged into a system module.

 class Program{
        public static void Main()
        {
            Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer();
            s.Start();
            s.Update();
            s.OnDisable();
        }
    }

How can I fix this?

The important part of the Brekel library is as follows:

//======================================
    // Connect to Brekel TCP network socket
    //======================================
    private bool Connect()
    {
        // try to connect to the Brekel Kinect Pro Body TCP network streaming port
        try
        {
            // instantiate new TcpClient
            client = new TcpClient(host, port);

            // Start an asynchronous read invoking DoRead to avoid lagging the user interface.
            client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(FetchFrame), null);

            Debug.Log("Connected to Brekel Kinect Pro Body v2");
            return true;
        }
        catch (Exception ex)
        {
            Debug.Log("Error, can't connect to Brekel Kinect Pro Body v2!" + ex.ToString());
            return false;
        }
    }


    //===========================================
    // Disconnect from Brekel TCP network socket
    //===========================================
    private void Disconnect()
    {
        if (client != null)
            client.Close();
        Debug.Log("Disconnected from Brekel Kinect Pro Body v2");
    }

 public void Update()
{
    // only update if connected and currently not updating the data
    if (isConnected && !readingFromNetwork)
    {
        // find body closest to the sensor
        closest_skeleton_ID = -1;
        closest_skeleton_distance = 9999999f;
        for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
        {
            if (!skeletons[bodyID].isTracked)
                continue;
            if (skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z < closest_skeleton_distance)
            {
                closest_skeleton_ID = bodyID;
                closest_skeleton_distance = skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z;
            }
        }

        // apply to transforms (cannot be done in FetchFrame, only in Update thread)
        for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
        {
            for (int jointID = 0; jointID < skeletons[bodyID].joints.GetLength(0); jointID++)
            {
                // only apply if transform is defined
                if (skeletons[bodyID].joints[jointID].transform != null)
                {
                    // apply position only for waist joint
                    if (jointID == (int)brekelJoint.waist)
                        skeletons[bodyID].joints[jointID].transform.localPosition = skeletons[bodyID].joints[jointID].position_local;

                    // always apply rotation
                    skeletons[bodyID].joints[jointID].transform.localRotation = skeletons[bodyID].joints[jointID].rotation_local;
                }
            }
        }
Gabriel Britcher
  • 221
  • 1
  • 3
  • 16
  • Not familiar with this Brekel TCP library. Have a link? What does it do? – John Wu Jun 09 '15 at 16:28
  • It is rather lengthy, but the idea is to capture skeletal data from the Microsoft Kinect, stream the data instantaneously as someone is moving in the Kinects field of view, and then close the tcpip connection between the Brekel software and visual studio. I will paste the library in a comment below in case you want to see it. – Gabriel Britcher Jun 09 '15 at 16:33
  • 1
    possible duplicate (or just a related question) of http://stackoverflow.com/questions/11286004/securityexception-ecall-methods-must-be-packaged-into-a-system-module – David Schwartz Jun 09 '15 at 16:35
  • My code gives the same error, but I am not even compiling, it can't even make it through debugging. Also everything in my script is public in order to make it available to call. – Gabriel Britcher Jun 09 '15 at 16:41
  • Where is the error occurring in the library code you just pasted? What line? – David Schwartz Jun 09 '15 at 16:44
  • The error isn't in the library code, it is when I call the instance of the method in my Main method. Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer(); – Gabriel Britcher Jun 09 '15 at 16:46
  • I just added the library because John Wu had asked for it. – Gabriel Britcher Jun 09 '15 at 16:47
  • It may be something in the constructor, can you post the code for the constructor of the class? – Ron Beyer Jun 09 '15 at 16:47
  • If it has one, include the static constructor as well. – David Schwartz Jun 09 '15 at 16:49
  • public class Brekel_ProBody2_TCP_Streamer : MonoBehaviour { – Gabriel Britcher Jun 09 '15 at 16:50
  • Please add the constructor to the question, it makes it much easier to read. What you posted there is the definition of the class, not the constructor... – Ron Beyer Jun 09 '15 at 16:50
  • Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer(); – Gabriel Britcher Jun 09 '15 at 16:52
  • @GabrielBritcher I found a random knowledge base page that says this error may be the result of a problem with the installation of the .NET Framework. It recommends doing a repair. May be worth a try. (link: http://kb.lathem.com/index.php?/Knowledgebase/Article/View/743/27/ecall-methods-must-be-packaged-into-a-system-module) – David Schwartz Jun 09 '15 at 16:53
  • Would that not be the constructor? I am sorry for any confusion, I am new to coding and have never used C# other than a YouTube tutorial. The help is very much appreciated!! – Gabriel Britcher Jun 09 '15 at 16:53
  • @GabrielBritcher, also not a constructor, the constructor is a method inside the class with the same name as the class itself, but does not have a return value, it should look like `public Brekel_ProBody2_TCP_Streamer() { ... }` – Ron Beyer Jun 09 '15 at 16:54
  • `MonoBehaviour `...does this mean you are using Unity? – Brandon Jun 09 '15 at 16:56
  • @David Schwartz I am working on the .NET Framework fix now, thank you! – Gabriel Britcher Jun 09 '15 at 17:06
  • @Brandon Yes I am using Unity. – Gabriel Britcher Jun 09 '15 at 17:06
  • @Ron Beyer This code was given to me and I am working on fixing it. There is no constructor, could that be part of the problem? Is a constructor necessary for every class? – Gabriel Britcher Jun 09 '15 at 17:06
  • I think Brandon is right about this one. – David Schwartz Jun 09 '15 at 17:07
  • No its not necessary. Are you using Unity *inside* Unity3D, or trying to use Unity by referencing `UnityEngine.dll` in your project? – Ron Beyer Jun 09 '15 at 17:07
  • I am referencing UnityEngine.dll – Gabriel Britcher Jun 09 '15 at 17:09
  • 1
    You can't do that, you can't use UnityEngine outside of Unity. – Ron Beyer Jun 09 '15 at 17:09

3 Answers3

29

It appears you are using a Unity library but trying to run it as a standalone application?

This error means you are calling a method that is implemented within the Unity engine. You can only use the library from within Unity.

If you want to use it standalone, you'll need to compile the library without referencing any Unity libraries, which probably means you'll need to provide implementations for anything the library is using (such as MonoBehaviour

http://forum.unity3d.com/threads/c-error-ecall-methods-must-be-packaged-into-a-system-module.199361/

http://forum.unity3d.com/threads/security-exception-ecall-methods-must-be-packaged-into-a-system-module.98230/

Brandon
  • 38,310
  • 8
  • 82
  • 87
  • Theoretically, could I just copy and past my code into Unity rather than making it standalone? I have no reason that it needs to be standalone. – Gabriel Britcher Jun 09 '15 at 17:15
2

Additionally, If your only problem is Debug.Log() throwing an exception, you could use reflection to plant your own Logger instance instead of Unity's one.

Step 1: Create "MyLogHandler" that will do your actual logging(write to file or to console or do nothing). Your class needs to implement "ILogHandler" interface.

Step 2: Replace unity default one with new one.

var newLogger = new Logger(new MyLogHandler());
var fieldInfo = typeof(Debug).GetField("s_Logger", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
        fieldInfo.SetValue(null, newLogger);

Note: Keep in mind that reflection accesses field by name and if Unity decide to change it in future, you will not get compile error - exception will be thrown in run-time.

Aleksandar
  • 21
  • 1
1

I know this is old, but I came across a way to unit test Unity assemblies from within Visual Studio just by toggling a symbol definition from the Unity build settings. As long as you're OK with only being either able to either run tests or have the testable components usable in unity at one time, you can toggle unit testing mode and unity mode like this (images follow):

  1. Make your unity component a partial class. Have one file where you declare that the partial class extends MonoBehaviour and put any stuff that has to actually use unity assemblies in there. This will not be tested by the unit tests but everything else will.
  2. Use conditional compilation to make that file's contents only compile when a specific symbol is defined during the build. I used UNIT_TEST_NO_UNITY_INTEGRATION in my case.
  3. When you want to run the unit tests from Visual Studio, update the build settings to define that symbol. This will exclude the Unity specific stuff from step 1 from the build and allow Visual Studio to be able to run your unit tests.
  4. When you are finished testing, edit the build settings again and remove that symbol definition. Now your unit tests won't be able to run but your assemblies will work within Unity again.

enter image description here enter image description here

S.C.
  • 1,152
  • 8
  • 13