C#安全异常

17
运行程序时,我一直收到以下错误提示: 发生未处理的类型为“System.Security.SecurityException”的异常 附加信息:ECall方法必须打包进系统模块中。
 class Program{
        public static void Main()
        {
            Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer();
            s.Start();
            s.Update();
            s.OnDisable();
        }
    }

请问我该如何解决这个问题?

Brekel库的重要部分如下:

//======================================
    // 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;
                }
            }
        }

1
可能是重复的问题(或相关问题)https://dev59.com/4Ggu5IYBdhLWcg3wfHE_ - David Schwartz
错误不在库代码中,而是在我的Main方法中调用方法实例时出现。Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer(); - Gabriel Britcher
可能是构造函数中的某些问题,您能否发布该类的构造函数代码? - Ron Beyer
公共类 Brekel_ProBody2_TCP_Streamer: MonoBehaviour - Gabriel Britcher
1
你不能这样做,你不能在Unity之外使用UnityEngine。 - Ron Beyer
显示剩余18条评论
3个回答

29

看起来你正在使用Unity库,但尝试将其作为独立应用程序运行?

这个错误意味着你正在调用在Unity引擎内实现的方法。你只能从Unity内部使用该库。

如果你想独立使用它,将需要编译该库而不引用任何Unity库,这可能意味着你需要提供该库正在使用的所有东西的实现(例如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/


理论上,我可以直接将我的代码复制粘贴到Unity中,而不是使其独立运行吗?我没有理由让它成为独立的。 - Gabriel Britcher

2
此外,如果您唯一的问题是 Debug.Log() 抛出异常,您可以使用反射来替换 Unity 默认的 Logger 实例,从而使用您自己的 Logger 实例。
步骤1:创建“MyLogHandler”,它将进行实际日志记录(写入文件或控制台或什么都不做)。您的类需要实现“ILogHandler”接口。
步骤2:用新的 MyLogHandler 替换 Unity 的默认 LogHandler。
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);

注意:请记住,反射是通过名称访问字段的,如果Unity在未来决定更改它,您将不会得到编译错误 - 异常将在运行时抛出。


1
我知道这已经是老方法了,但我找到了一种方法,可以通过从Unity构建设置中切换符号定义来在Visual Studio中对Unity程序集进行单元测试。只要你只能运行测试或在Unity中使用可测试组件之间进行切换,你就可以像这样切换单元测试模式和Unity模式(以下是图片):
  1. 将Unity组件变成部分类。有一个文件声明部分类扩展MonoBehaviour并放置任何必须实际使用Unity程序集的内容。这不会被单元测试测试,但其他所有内容都会。
  2. 使用条件编译使该文件的内容仅在构建期间定义特定符号时编译。在我的情况下,我使用了UNIT_TEST_NO_UNITY_INTEGRATION
  3. 当您想从Visual Studio运行单元测试时,请更新构建设置以定义该符号。这将从步骤1中排除Unity特定的内容,并允许Visual Studio能够运行您的单元测试。
  4. 完成测试后,再次编辑构建设置并删除该符号定义。现在,您的单元测试将无法运行,但您的程序集将再次在Unity中工作。

enter image description here enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接