P /在/ MT或/ MD

时间:2015-12-15 20:06:39

标签: c# c++ pinvoke wrapper

我为CryptoPP编写了一个包装器,它将由c#app使用。 我的问题是,当使用PInvoke调用我的包装器中的特定函数时,抛出异常“尝试读取或写入受保护的内存...”。 它们都编译为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 []等......仍然抛出异常。

等待我的救世主......

谢谢。

2 个答案:

答案 0 :(得分:1)

你是对的,你不能分发调试运行时,但事实上问题并不是你想的那么。许可证不允许重新分发调试运行时。

最可能的解释是,您的代码存在缺陷。缺陷不会在调试运行时出现的事实简直就是机会。因此,正确的方法是追踪您的缺陷并进行修复。

答案 1 :(得分:0)

考虑使用托管代码和非托管代码之间的桥梁。 它可以更容易调试......

示例:

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