繁体   English   中英

C#DllImport麻烦

[英]C# DllImport trouble

我的问题有点笼统,所以我不是在寻找一个确切的答案,但可能有一些方向可以帮助我......

在我的工作场所,我主要用C#编程。 我们有这个与我们合作的第三方公司,它给了我们一个我们需要使用的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);

3rd Edit:我改变了方法的签名

extern "C" __declspec(dllexport) bool CreateRsaHash(char *inputPass, char *hashPass);

并且我要查找的返回值放在*hashPass参数中。

现在,我创建了一个简单的控制台应用程序来测试它。 在我的主类中插入DllImport,并直接调用该方法时,一切都很好,但是当我移动DllImport并将该方法包装在另一个类中并从Console'Main'方法调用该类时,我得到一个StackOverflow异常!

有人知道为什么会这样吗?

在将StringBuilder传递给interop方法之前,请尝试指定它的容量

从稀疏的信息中很难知道但是如果我不得不猜测我会说你需要确保你固定输出对象。 另外我可能会将输出参数更改为其他类型,看起来很奇怪StringBuilder可以坦率地工作。

我知道如果你分配一个对象,它会得到一个指针,但这并不意味着它不会移动。 因此,如果您尝试将指向托管对象的指针传递到非托管环境中,则需要确保告诉GC“固定”内存,以便它不会从您的下方移出。

这是一个非常粗略的版本,我的意思是固定:

string input = "...";
StringBuilder output = new StringBuilder();
var handle = System.Runtime.InteropServices.GCHandle.Alloc(output, GCHandleType.Pinned);
try
{
    CreateHash(input, output);
}
finally
{
    handle.Free();
}

我会考虑在C#shared assembly / dll而不是c ++ dll中进行扭曲,然后尝试让你的控制台应用程序与dll一起工作。 无论如何,最好以这种方式包装外部依赖项。
否则,一些传统问题是32比64位,即共享库的加载路径。 它真的只是一个字符串或更复杂的东西吗?

我找到了我的问题的解决方案,现在我感觉有点(如果不是真的!)愚蠢...: - |

我在C ++中使用LoadLibrary()方法从其他本机dll动态调用方法。 问题是我没有给方法任何路径,只有dll文件名。 在.net中,它会在当前文件夹中搜索,但在本机代码中似乎不会以这种方式工作。

我的编程实践中的更大问题显然是我没有完全覆盖我的本机C ++ DLL中的错误处理!

我在这个页面收到的所有收据都不是没有...

一旦我发现我的目录路径有问题,我遇到了关于尝试访问损坏的内存等的不同异常。然后我需要创建固定对象,并为我的StringBuilder对象声明一个大小。

感谢大家的帮助!!

:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM