P/Invoke "Protected Memory" /MT 或 /MD 异常
P/Invoke "Protected Memory" exception on /MT or /MD
我已经为 C# 应用程序使用的 CryptoPP 编写了一个包装器。
我的问题是,当使用 PInvoke 调用包装器中的特定函数时,抛出异常 "Attempted to read or write protected memory..."。
它们都被编译为 x64.
现在.. 奇怪的是 如果我使用 /MTd 或 /MDd 运行时编译我的包装器,调用不会失败并且一切正常。 但是将运行时更改为/MT 或 /MD 会抛出上述异常。
我无法使用 /MTd 或 /MDd 选项供我的客户正式使用,因为它需要将大量 dll 资源安装或分发到用户计算机中。
cpp代码:
extern "C" __declspec(dllexport) int CryptBlock(bool mode, unsigned char type, unsigned char *inData, unsigned char *outData, int dataLen, unsigned char *key, int keyLen);
c# PInvoke:
[DllImport("mydll.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int CryptBlock(bool mode, byte type, IntPtr inData, IntPtr outData, int dataLen, IntPtr key, int keyLen);
我尝试过以各种方式修改我的 P/Invoke 代码:
[In, Out], [Out], ref, ref byte[], byte[] 等...仍然抛出异常。
等待我的救星...
谢谢。
考虑使用托管代码和非托管代码之间的桥梁。
它可以更容易地调试...
示例:
C++ 非托管代码:
class ExampleCpp
{
private:
int id;
public:
ExampleCpp();
~ExampleCpp();
const int getId();
};
C++ 托管代码:
public ref class ExampleManagedCpp
{
private:
ExampleCpp* pImpl;
public:
ExampleManagedCpp();
~ExampleManagedCpp();
!ExampleManagedCpp();
};
http://www.codeproject.com/Articles/868230/Cplusplus-CLI-Accessing-a-managed-type-from-unmana
http://blogs.msdn.com/b/soultech/archive/2010/07/27/cli-c_2b002b00_-to-c_2300_-hello-world.aspx
你是对的,你不能分发调试运行时,但实际上问题并不像你想的那样。该许可证不允许重新分发调试运行时。
最可能的解释实际上是您的代码存在缺陷。调试运行时没有显示缺陷的事实完全是偶然的。所以正确的方法是找到你的缺陷并修复它。
我已经为 C# 应用程序使用的 CryptoPP 编写了一个包装器。 我的问题是,当使用 PInvoke 调用包装器中的特定函数时,抛出异常 "Attempted to read or write protected memory..."。 它们都被编译为 x64.
现在.. 奇怪的是 如果我使用 /MTd 或 /MDd 运行时编译我的包装器,调用不会失败并且一切正常。 但是将运行时更改为/MT 或 /MD 会抛出上述异常。
我无法使用 /MTd 或 /MDd 选项供我的客户正式使用,因为它需要将大量 dll 资源安装或分发到用户计算机中。
cpp代码:
extern "C" __declspec(dllexport) int CryptBlock(bool mode, unsigned char type, unsigned char *inData, unsigned char *outData, int dataLen, unsigned char *key, int keyLen);
c# PInvoke:
[DllImport("mydll.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int CryptBlock(bool mode, byte type, IntPtr inData, IntPtr outData, int dataLen, IntPtr key, int keyLen);
我尝试过以各种方式修改我的 P/Invoke 代码: [In, Out], [Out], ref, ref byte[], byte[] 等...仍然抛出异常。
等待我的救星...
谢谢。
考虑使用托管代码和非托管代码之间的桥梁。 它可以更容易地调试...
示例:
C++ 非托管代码:
class ExampleCpp
{
private:
int id;
public:
ExampleCpp();
~ExampleCpp();
const int getId();
};
C++ 托管代码:
public ref class ExampleManagedCpp
{
private:
ExampleCpp* pImpl;
public:
ExampleManagedCpp();
~ExampleManagedCpp();
!ExampleManagedCpp();
};
http://www.codeproject.com/Articles/868230/Cplusplus-CLI-Accessing-a-managed-type-from-unmana
http://blogs.msdn.com/b/soultech/archive/2010/07/27/cli-c_2b002b00_-to-c_2300_-hello-world.aspx
你是对的,你不能分发调试运行时,但实际上问题并不像你想的那样。该许可证不允许重新分发调试运行时。
最可能的解释实际上是您的代码存在缺陷。调试运行时没有显示缺陷的事实完全是偶然的。所以正确的方法是找到你的缺陷并修复它。