簡體   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