簡體   English   中英

為什么在C#項目中看不到某些C ++ DLL(支持CLR)?

[英]Why can't i see some C++ DLL ( support CLR ) in C# project ?

我編寫了簡單的C ++ Dll(win32),並將屬性更改為“公共語言運行時支持(/ clr)”-

我創建了一個新的Simple winform項目(C#4.0),並創建了對C ++項目(C ++ DLL)的引用。

現在,我在C#項目中看不到C ++ dll-我無法使用它,我也不知道為什么。

您在C ++ dll中創建的類型仍然是本機的。 您需要將它們顯式聲明為托管類型。 例如:

ref class SomeType { }

聲明一個托管類(請注意ref關鍵字)。 這並不是那么容易。 您的本機代碼不會神奇地轉換為托管代碼(一些基本數據類型,例如int ,但不是std::string類的東西)。 如果您真的想充分利用C ++ / CLI進行互操作,則應該花一些時間來學習語法差異。

例如,如果您具有以下非托管功能:

bool fooFunction(int firstParameter, int secondParameter);

如果要使其對托管代碼可見,則必須將其包裝(作為第一個簡單步驟):

public ref class MyClass abstract sealed
{
public:
    static bool Foo(int firstParameter, int secondParameter)
    {
        return fooFunction(firstParameter, secondParameter);
    }
};

這是一個簡單的考試,如果您必須與復雜類型互操作,則可能需要將它們全部包裝起來。 例如,如果您必須與接受字符串的函數互操作,則必須對此進行管理。 通常我使用這樣的類:

ref class UnmanagedString sealed
{
public:
    UnmanagedString(String^ content) : _content(content)
    { 
        _unicodePtr = _ansiPtr = IntPtr::Zero; 
    }

    ~UnmanagedString()
    { 
        Free(); 
    }

    operator LPWSTR()
    { 
        if (_content == nullptr)
            return NULL;

        Free();

        _unicodePtr = Marshal::StringToHGlobalUni(_content);
        return reinterpret_cast<LPWSTR>(_unicodePtr.ToPointer());
    }

    operator LPCSTR()
    { 
        if (_content == nullptr)
            return NULL;

        Free();

        _ansiPtr = Marshal::StringToHGlobalAnsi(_content);
        return reinterpret_cast<LPCSTR>(_ansiPtr.ToPointer());
    }

    virtual System::String^ ToString() override
    {
        return _content;
    }

    virtual int GetHashCode() override
    {
        return _content->GetHashCode();
    }

    virtual bool Equals(Object^ obj) override
    {
        return _content->Equals(obj);
    }

private:
    IntPtr _unicodePtr, _ansiPtr;
    String^ _content;

    void Free()
    {
        if (_unicodePtr != IntPtr::Zero)
        {
            Marshal::FreeHGlobal(_unicodePtr);
            _unicodePtr = IntPtr::Zero;
        }

        if (_ansiPtr != ntPtr::Zero)
        {
            Marshal::FreeHGlobal(_ansiPtr);
            _ansiPtr = IntPtr::Zero;
        }
    }
};

使用此類,您可以使用foo(UnamangedString(myManagedString))調用void foo(LPCSTR pszText)類的函數。 更復雜的是您必須執行的調用以及要編寫的互操作代碼。

注意:簡單地將1:1托管接口暴露給非托管函數將使您的C#代碼難以閱讀,我建議您編寫一個真正的OO接口以隱藏基礎實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM