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

放肆的年华 提交于 2020-01-03 05:10:38

问题


I wrote simple C++ Dll ( win32 ) and i change the properties to be 'Common Language Runtime Support (/clr)' -

I created new Simple winform project ( C# 4.0 ) and i created reference to the C++ project ( the C++ DLL ).

Now i can't see the C++ dll in the C# project - i cant use it and i dont know why.


回答1:


If you have, for example, this unmanaged function:

bool fooFunction(int firstParameter, int secondParameter);

If you want to make it visible to managed code you have to wrap (as first, simple, step) it into a managed class:

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

This is a simple exam, if you have to interop with complex type you may need to wrap them all. For example if you have to interop with a function that accepts a string you have to manage this. Usually I use a class like this:

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;
        }
    }
};

Using this class you can call a function like void foo(LPCSTR pszText) with foo(UnamangedString(myManagedString)). More complex are the calls you have to do and more code you have to write to interop between them.

Note: simply exposing a 1:1 managed interface to unmanaged functions will make your C# code harder to read, I suggest you write a true OO interface to hide underlying implementation.




回答2:


The types you created in your C++ dll are still native. You need to explicitly declare them as managed types. For example:

ref class SomeType { }

declares a managed class (note the ref keyword). It's not quite that easy though. Your native code won't get magically converted to managed code (a few basic data types like int are, but not things like std::string). If you really want to take full advantage of C++/CLI for interop, you should take the time to learn about the syntax differences.



来源:https://stackoverflow.com/questions/10881559/why-cant-i-see-some-c-dll-support-clr-in-c-sharp-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!