如何在C#应用程序中使用C ++ / CLI

| 我正在尝试从C#应用程序(通过C ++ / CLI)调用C ++库。我遵循了这个问题的示例(针对我的特定应用)。我的应用程序的设置是: Project1:C ++项目(我将其编译为DLL) Project2:C ++项目(我的CLR包装器;仅上述示例中的头文件;引用Project1) Project3:C#项目(引用Project2) 不幸的是,当我实际上去访问C#应用程序中的CLR包装器对象时,收到以下错误:   类型或名称空间名称\'YourClass \'   找不到(您是否错过了   使用指令或程序集   参考?) 我的项目设置是否有误,还是应该考虑其他事项? (不幸的是,由于专有原因,我无法发布代码,但这是一段非常简单的代码,可以轻松地遵循上述示例。) 更新: 因此,我完全按照Chris所说的去做(请参见下面的答案),但是我仍然从C#应用程序中收到一条消息,提示找不到“类型或名称空间名称\'MyProgram \'(您是否缺少using指令)还是程序集引用?)这是我的代码(模型)。 Project1-这是我的C ++应用程序。它编译/工作。我在其他地方用过。 (我从此版本中获得了一个DLL。) Project2-这是我包装的代码。 MyWrapper.h
#pragma once

#include \"myorigapp.h\"

using namespace System;

namespace MyProgram
{
    public ref class MyWrapper
    {
    private:
        myorigapp* NativePtr;

    public:
        MyWrapper() 
        {
            NativePtr = new myorigapp();
        }

        ~MyWrapper() 
        { 
            delete NativePtr;
            NativePtr = NULL;
        }

        void dostuff()
        { 
            NativePtr->dostuff(); 
        }
    }
}
Project3-这是我的C#应用​​程序。 Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MyProgram;

namespace Testing
{
    class Program
    {
        static void Main(string[] args)
        {
            MyWrapper p = new MyWrapper();
            p.dostuff();
        }
    }
}
Project3引用引用Project1的Project2。一切构建都没有错误(除了我在
using MyProgram
行的C#代码中上面描述的错误)。     
已邀请:
仅包含纯C ++应用程序的标头还不够。您需要在Project2中将非托管对象与托管对象包装在一起(即
public ref class YourClassDotNet
#include \"YourHeader.h\"

namespace MyManagedWrapper
{
    public ref class YourClassDotNet
    {
    private:
        YourClass* ptr;

    public:
        YourClassDotNet()
        {
            ptr = new YourClass();
        }

        ~YourClassDotNet()
        {
            this->!YourClassDotNet();
        }

        !YourClassDotNet()
        {
            delete ptr;
            ptr = NULL;
        }

        void SomeMethod()
        {
            ptr->SomeMethod();
        }
    }
}
    
好的,我现在觉得很蠢。 事实证明,我遇到的问题(几周前已经解决了-只是更新了这个答案)是我包含了头文件(有关此信息,请参见Chris的答案),但我没有实际上包含了CPP文件(除了包含头文件之外,该文件为空)。 完成此操作后,DLL将正确编译,并且可以从C#代码中调用C ++函数(使用C ++ / CLI)。     
克里斯向您展示了创建内部使用非托管代码的托管类的方法。您可以使用不安全的方法在C#中进行很多操作(几乎没有人可以做到)。 但是,也可以相反:直接从本机类型/函数使用.NET类型。 需要注意的是,任何托管指针都必须这样标记。为此,C ++ / CLI定义了一种特殊类型的smartpointer
gcroot<T>
(以某种方式模仿boost :: shared_pointer或std :: auto_ptr)。因此,要将托管字符串存储在C ++类中,请使用以下命令:
#include <string>
#include <vcclr.h>
using namespace System;

class CppClass {
public:
   gcroot<String^> str;   // can use str as if it were String^
   CppClass(const std::string& text) : str(gcnew String(text.c_str())) {}
};

int main() {
   CppClass c(\"hello\");
   c.str = gcnew String(\"bye\");
   Console::WriteLine( c.str );   // no cast required
}
请注意(如果这几天还没有解决),托管
null
和C / C ++ NULL之间的不匹配会引起一些摩擦。 您不能像您期望的那样轻松键入:
gcroot<Object^> the_thing;
...
if (the_thing != nullptr)
 ...
}
取而代之的是,您必须使用本机样式(由智能包装器
gcroot
处理)
gcroot< Object^ > the_thing;
if ( the_thing != NULL ) {} // or equivalently...
if ( the_thing ) {}

// not too sure anymore, but I thought the following is also possible:
if ( the_thing != gcroot<Object>(nullptr) ) {}
注意:最近几天,我都无法访问Windows计算机,因此我引用了内存     

要回复问题请先登录注册