调用本机C++ C++/cli的方法

发布于 2025-01-22 12:38:00 字数 1085 浏览 0 评论 0原文

我正在使用带有Visual Studio的.NET图形接口在C ++中开发Wordle。我有一个file.h,其中包含一个“ worddatabase”类,我需要在我的主体中使用此类的一种方法,以便为此,我试图在主文件中创建一个对象的实例,但是它不允许我执行此操作,并且显示此错误

 <C++ gcnew cannot allocate an entity of type>

这是类的代码:

#pragma once
#include <vector>
#include <random>
class WordDatabase
{
    public:
        // Initialises the word database with the associated file
        WordDatabase(std::default_random_engine& randomEngine);
        virtual ~WordDatabase() = default;

        // Returns a random word from the database.
        std::string getRandomWord() const;

};

这是我调用函数的主代码

#include "MyForm.h"
#include "WordDatabase.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]

void main(array<String^>^ args)
{
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Project2::MyForm form;
    WordDatabase wdb = gcnew WordDatabase();
    String^ solution = getRandomWord();
    Application::Run(% form);
}

I'm developing Wordle in C++ using a .net graphic interface with visual studio. I have a file.h that contains a class "WordDatabase", and I need to use one of the methods of this class in my main, In order to do this I was trying to create an instance of the object in my main file but it doesn't allow me to do it and it displays this error

 <C++ gcnew cannot allocate an entity of type>

This is the code for the class:

#pragma once
#include <vector>
#include <random>
class WordDatabase
{
    public:
        // Initialises the word database with the associated file
        WordDatabase(std::default_random_engine& randomEngine);
        virtual ~WordDatabase() = default;

        // Returns a random word from the database.
        std::string getRandomWord() const;

};

and this is the code of the main where I call the function

#include "MyForm.h"
#include "WordDatabase.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]

void main(array<String^>^ args)
{
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Project2::MyForm form;
    WordDatabase wdb = gcnew WordDatabase();
    String^ solution = getRandomWord();
    Application::Run(% form);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小傻瓜 2025-01-29 12:38:00

按照上面的评论,这是使用C ++/CLI包装器类的C ++/CLI main 的完整示例,将实现委派给C ++常规类。

根据我的经验,最好投入时间并将C ++(IE本地)部分和C ++/CLI(IE管理)部分分开。

这是 c ++ 类标头:

// Example.h:
#pragma once
#include <string>
class Example
{
public:
    Example(/*...*/) { /*...*/ }
    std::string GetString();
};

实现:

// Example.cpp:
#include "Example.h"
std::string Example::GetString()
{
    return "some_string";
}

这是 c ++/cli/cli wrapper ref class用于A中的标题。网络环境:

// ExampleCliWrapper.h
#pragma once
class Example;  // forward declaration
public ref class ExampleCliWrapper
{
public:
    ExampleCliWrapper(/*...*/);
    virtual ~ExampleCliWrapper();
    System::String^ GetString();
private:
    Example * m_pExample;
};

和实现:

// ExampleCliWrapper.cpp
#include "ExampleCliWrapper.h"
#include "Example.h"
ExampleCliWrapper::ExampleCliWrapper(/*...*/)
{
    m_pExample = new Example(/*...*/);
    //...
}
/*virtual*/ ExampleCliWrapper::~ExampleCliWrapper()
{
    delete m_pExample;
}
System::String^ ExampleCliWrapper::GetString()
{
    std::string strCpp = m_pExample->GetString();
    return gcnew System::String(strCpp.c_str());
}

请注意,最后一个方法执行了std :: StringSystem :: String^之间的转换。

最后,main全部使用:

// main.cpp
#include "ExampleCliWrapper.h"
int main(array<System::String ^> ^args)
{
    ExampleCliWrapper ^ exampleCli = gcnew ExampleCliWrapper(/*...*/);
    System::String ^ strCli = exampleCli->GetString();
    System::Console::WriteLine(strCli);
    return 0;
}

注意 - 我使用了一个原始指针,而不是std :: simelod_ptr,因为C ++/CLI编译器不支持使用之类的类使用类std :: unique_ptr(称为混合类型)。也许有办法解决,不确定。

Following my comments above, here's a complete example of a C++/CLI main using a C++/CLI wrapper class delegating the implementation to a C++ regular class.

In my experience it is better to invest the time and separate the C++ (i.e. native) part, and the C++/CLI (i.e. managed) part.

This is the C++ class header:

// Example.h:
#pragma once
#include <string>
class Example
{
public:
    Example(/*...*/) { /*...*/ }
    std::string GetString();
};

And implementation:

// Example.cpp:
#include "Example.h"
std::string Example::GetString()
{
    return "some_string";
}

And this is the header of the C++/CLI wrapper ref class to be used in a .NET environment:

// ExampleCliWrapper.h
#pragma once
class Example;  // forward declaration
public ref class ExampleCliWrapper
{
public:
    ExampleCliWrapper(/*...*/);
    virtual ~ExampleCliWrapper();
    System::String^ GetString();
private:
    Example * m_pExample;
};

And implementation:

// ExampleCliWrapper.cpp
#include "ExampleCliWrapper.h"
#include "Example.h"
ExampleCliWrapper::ExampleCliWrapper(/*...*/)
{
    m_pExample = new Example(/*...*/);
    //...
}
/*virtual*/ ExampleCliWrapper::~ExampleCliWrapper()
{
    delete m_pExample;
}
System::String^ ExampleCliWrapper::GetString()
{
    std::string strCpp = m_pExample->GetString();
    return gcnew System::String(strCpp.c_str());
}

Note that the last method performed the conversion between std::string and System::String^.

Finally the main that uses it all:

// main.cpp
#include "ExampleCliWrapper.h"
int main(array<System::String ^> ^args)
{
    ExampleCliWrapper ^ exampleCli = gcnew ExampleCliWrapper(/*...*/);
    System::String ^ strCli = exampleCli->GetString();
    System::Console::WriteLine(strCli);
    return 0;
}

Note - I used a raw pointer instead of std::unique_ptr because the C++/CLI compiler does not support using classes like std::unique_ptr (refered to as mixed types). Maybe there's a way around it, not sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文