简体   繁体   English

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

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

I wrote simple C++ Dll ( win32 ) and i change the properties to be 'Common Language Runtime Support (/clr)' - 我编写了简单的C ++ Dll(win32),并将属性更改为“公共语言运行时支持(/ clr)”-

I created new Simple winform project ( C# 4.0 ) and i created reference to the C++ project ( the C++ DLL ). 我创建了一个新的Simple winform项目(C#4.0),并创建了对C ++项目(C ++ DLL)的引用。

Now i can't see the C++ dll in the C# project - i cant use it and i dont know why. 现在,我在C#项目中看不到C ++ dll-我无法使用它,我也不知道为什么。

The types you created in your C++ dll are still native. 您在C ++ dll中创建的类型仍然是本机的。 You need to explicitly declare them as managed types. 您需要将它们显式声明为托管类型。 For example: 例如:

ref class SomeType { }

declares a managed class (note the ref keyword). 声明一个托管类(请注意ref关键字)。 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 ). 您的本机代码不会神奇地转换为托管代码(一些基本数据类型,例如int ,但不是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. 如果您真的想充分利用C ++ / CLI进行互操作,则应该花一些时间来学习语法差异。

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)) . 使用此类,您可以使用foo(UnamangedString(myManagedString))调用void foo(LPCSTR pszText)类的函数。 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. 注意:简单地将1:1托管接口暴露给非托管函数将使您的C#代码难以阅读,我建议您编写一个真正的OO接口以隐藏基础实现。

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

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