【发布时间】:2011-05-24 12:33:40
【问题描述】:
我的问题有点笼统,所以我不是在寻找确切的答案,但可能一些研究方向会对我有所帮助...
在我的工作场所,我主要使用 C# 进行编程。 我们有这家与我们合作的第 3 方公司,它为我们提供了我们需要使用的 Native C++ dll。 由于我需要的 C++ 方法没有以易于从 C# 引用的方式公开,因此我将 dll 包装在另一个 Native C++ Dll 中。
所以现在我有 2 个 Native C++ dll,一个包裹另一个。
我创建了一个小型 C# 控制台应用程序,它调用我在 C++ 中创建的方法。 我的方法签名如下所示:
[DllImport("HashMethodWrapper.dll")]
[return: MarshalAs(UnmanagedType.LPStr)]
private static extern string CreateHash(
string input,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder output);
在我的控制台应用程序中,一切正常,我总是收到我期望的字符串。
但是当我将它移动到我创建的 Web 服务或 Web 应用程序时(因为这是我真正需要它的地方),我看到我收到的字符串是垃圾,甚至不一致。似乎我只是得到了一些对丢失的记忆的引用或类似的东西,但这只是我的猜测......
我不知道为什么会这样,因为在我的控制台应用程序中一切正常。
有没有人有方向可以帮助我???...
提前致谢, 吉利布
编辑: 我认为这可能与一些未固定的对象有关,所以我尝试在固定语句中调用该方法,例如:
unsafe public static string CreateHashWrap(string pass)
{
String bb;
StringBuilder outPass = new StringBuilder();
fixed (char* resultStr = CreateHash(pass, outPass))
{
bb = new String(resultStr);
}
return bb;
}
...但这仍然没有为我做。这是固定对象的正确方法吗?
第二次编辑: C++ 中的方法签名如下所示:
extern "C" __declspec(dllexport) char *CreateRsaHash(char *inputPass, char *hashPass);
第三次编辑: 我将方法的签名更改为
extern "C" __declspec(dllexport) bool CreateRsaHash(char *inputPass, char *hashPass);
我要查找的返回值放在*hashPass参数中。
现在,我创建了一个简单的控制台应用程序来测试它。当在我的主类中插入 DllImport 并直接调用该方法时,一切正常,但是当我移动 DllImport 并将该方法包装在另一个类中并从控制台的“Main”方法中调用该类时,我得到了 StackOverflow 异常!
有人知道为什么会这样吗??
【问题讨论】:
-
你能告诉我们函数头是如何在 C/C++ 中声明的吗?这可能会有所帮助:)
-
杀死API作者,有很明显的内存泄漏发生...
-
为什么???你能解释一下为什么吗,为什么从签名上看这么清楚??希望我们仍然可以修复它!
-
返回指向任何非常量“对象”的指针是一个确定的信号...方法 sig 可能是“错误的”,但从它的外观来看,它无论如何都不会返回一个常量值......也许确实如此,我不知道,但它只是用斧头刺伤了我的眼睛......
-
@gillyb:如果可能的话,但我不知道如何,因为我可以推断出每次调用的返回值都会改变。最好的方法是传递预先分配的缓冲区(又名具有容量的 StringBuilder)以及指定每个传递的缓冲区的大小。否则你可以使用固定的字节/字符[]。
标签: c# asp.net pinvoke unmanaged