C# 安全异常
C# Security Exception
当运行这个程序我一直收到错误:
发生 '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;
}
}
}
看来您正在使用 Unity 库,但试图 运行 将其作为独立应用程序?
此错误意味着您正在调用在 Unity 引擎中实现的方法。您只能在 Unity 中使用该库。
如果您想独立使用它,则需要在不引用任何 Unity 库的情况下编译库,这可能意味着您需要为库使用的任何内容提供实现(例如 MonoBehaviour
http://forum.unity3d.com/threads/c-error-ecall-methods-must-be-packaged-into-a-system-module.199361/
此外,
如果你唯一的问题是 Debug.Log() 抛出异常,你可以使用反射来植入你自己的 Logger 实例而不是 Unity 的实例。
第 1 步: 创建 "MyLogHandler",它将执行您的实际日志记录(写入文件或控制台或什么也不做)。您的 class 需要实现 "ILogHandler" 接口。
第 2 步: 用新的替换统一默认值。
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 决定将来更改它,您将不会遇到编译错误 - 异常将在 运行-次.
我知道这已经过时了,但我发现了一种从 Visual Studio 中对 Unity 程序集进行单元测试的方法,只需切换 Unity 构建设置中的符号定义即可。只要您同意只能进行 运行 测试或让可测试组件一次统一使用,您就可以像这样切换单元测试模式和统一模式(如下图):
- 使您的 unity 组件成为部分组件 class。有一个文件,您声明部分 class 扩展
MonoBehaviour
并将任何必须实际使用统一程序集的东西放在那里。这不会被单元测试测试,但其他一切都会。
- 使用条件编译使该文件的内容仅在构建过程中定义了特定符号时才编译。我在我的案例中使用了
UNIT_TEST_NO_UNITY_INTEGRATION
。
- 当您想要 运行 来自 Visual Studio 的单元测试时,更新构建设置以定义该符号。这将从构建中排除步骤 1 中特定于 Unity 的内容,并允许 Visual Studio 能够 运行 您的单元测试。
- 完成测试后,再次编辑构建设置并删除该符号定义。现在您的单元测试将无法 运行 但您的程序集将再次在 Unity 中运行。
当运行这个程序我一直收到错误: 发生 '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;
}
}
}
看来您正在使用 Unity 库,但试图 运行 将其作为独立应用程序?
此错误意味着您正在调用在 Unity 引擎中实现的方法。您只能在 Unity 中使用该库。
如果您想独立使用它,则需要在不引用任何 Unity 库的情况下编译库,这可能意味着您需要为库使用的任何内容提供实现(例如 MonoBehaviour
http://forum.unity3d.com/threads/c-error-ecall-methods-must-be-packaged-into-a-system-module.199361/
此外, 如果你唯一的问题是 Debug.Log() 抛出异常,你可以使用反射来植入你自己的 Logger 实例而不是 Unity 的实例。
第 1 步: 创建 "MyLogHandler",它将执行您的实际日志记录(写入文件或控制台或什么也不做)。您的 class 需要实现 "ILogHandler" 接口。
第 2 步: 用新的替换统一默认值。
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 决定将来更改它,您将不会遇到编译错误 - 异常将在 运行-次.
我知道这已经过时了,但我发现了一种从 Visual Studio 中对 Unity 程序集进行单元测试的方法,只需切换 Unity 构建设置中的符号定义即可。只要您同意只能进行 运行 测试或让可测试组件一次统一使用,您就可以像这样切换单元测试模式和统一模式(如下图):
- 使您的 unity 组件成为部分组件 class。有一个文件,您声明部分 class 扩展
MonoBehaviour
并将任何必须实际使用统一程序集的东西放在那里。这不会被单元测试测试,但其他一切都会。 - 使用条件编译使该文件的内容仅在构建过程中定义了特定符号时才编译。我在我的案例中使用了
UNIT_TEST_NO_UNITY_INTEGRATION
。 - 当您想要 运行 来自 Visual Studio 的单元测试时,更新构建设置以定义该符号。这将从构建中排除步骤 1 中特定于 Unity 的内容,并允许 Visual Studio 能够 运行 您的单元测试。
- 完成测试后,再次编辑构建设置并删除该符号定义。现在您的单元测试将无法 运行 但您的程序集将再次在 Unity 中运行。