使用CLR C ++包装器从C#应用程序加载C ++中的SDL窗口不起作用

问题描述 投票:1回答:1

我的应用程序的目标是通过C ++ CLR包装器从C#应用程序加载一个简单的SDL窗口。为了完成工作,我创建了3个项目:

  • 一个是加载SDL窗口(type = lib)的C ++库。
  • 第二个是用C ++ CLR(type = dll)编写的包装器。
  • 最后一个当然是C#基本应用程序(type = exe)。

C ++库:

包括:

#ifndef __TARGET_DISPLAY_HPP__
# define __TARGET_DISPLAY_HPP__

#include <SDL/SDL.h>

class TargetDisplay
{
    public:
        TargetDisplay(void);
        ~TargetDisplay(void);

    public:
        void Init(void);
        void Update(void);
        void Render(void);
        void Quit(void);
        bool IsAlive(void);

    private:
        SDL_Window *fenetre;
        SDL_GLContext contexteOpenGL;
        SDL_Event evenements;
        bool terminer;
};

#endif // !__TARGET_DISPLAY_HPP__

SRC:

#include "TargetDisplay.hpp"

//Initialization

TargetDisplay::TargetDisplay(void)
    :   terminer(false)
{

}

//Destruction

TargetDisplay::~TargetDisplay(void)
{

}

//Others

void TargetDisplay::Init(void)
{
    SDL_Init(SDL_INIT_VIDEO);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    fenetre = SDL_CreateWindow("Test SDL 2.0", SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED, 320, 240, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    contexteOpenGL = SDL_GL_CreateContext(fenetre);
}

void TargetDisplay::Update(void)
{
    SDL_WaitEvent(&evenements);

    if(evenements.window.event == SDL_WINDOWEVENT_CLOSE)
        terminer = true;
}

void TargetDisplay::Render(void)
{

}

bool TargetDisplay::IsAlive(void)
{
    return (true);
}

void TargetDisplay::Quit(void)
{
    SDL_GL_DeleteContext(contexteOpenGL);
    SDL_DestroyWindow(fenetre);
    SDL_Quit();
}

直到这里没什么特别的:只是SDL窗口的基本初始化(仅用于编译为.exe应用程序的代码正确显示窗口的信息)。

现在用CLR C ++编写的包装器:

包括:

#ifndef __WRAPPER_DISPLAY_HPP__
# define __WRAPPER_DISPLAY_HPP__

#include <iostream>
#include "../TargetCPP/TargetDisplay.hpp"

namespace Test
{
    public ref class WrapperDisplay
    {
        public:
            WrapperDisplay(void);
            ~WrapperDisplay(void);

        public:
            void Init(void);
            void Update(void);
            void Render(void);
            bool IsAlive(void);
            void Quit(void);

        private:
            TargetDisplay *m_pTarget;
    };
}

#endif // !__WRAPPER_DISPLAY_HPP__

SRC:

#include "WrapperDisplay.hpp"

//Initialization

Test::WrapperDisplay::WrapperDisplay(void)
{
    this->m_pTarget = new TargetDisplay();
}

//Destruction

Test::WrapperDisplay::~WrapperDisplay(void)
{

}

//Others

void Test::WrapperDisplay::Init(void)
{
    this->m_pTarget->Init();
}

void Test::WrapperDisplay::Update(void)
{
    this->m_pTarget->Update();
}

void Test::WrapperDisplay::Render(void)
{
    this->m_pTarget->Render();
}

bool Test::WrapperDisplay::IsAlive(void)
{
    return (this->m_pTarget->IsAlive());
}

void Test::WrapperDisplay::Quit(void)
{
    this->m_pTarget->Quit();
}

正如您所看到的,我已经在我的CLR项目中链接了我的C ++静态库,并且我调用了所有方法(如果我将CLR项目编译为.exe应用程序而将C ++项目编译为.lib应用程序,则SDL窗口正确显示太)。

最后是C#主应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WrapperTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Test.WrapperDisplay wrapper = new Test.WrapperDisplay();

            wrapper.Init();
            /*wrapper.Update();
            wrapper.Render();
            wrapper.Quit();*/
        }
    }
}

正如您所看到的,我只是调用包含在我的CLR包装器中的方法(这里,为了简单起见,我只调用'Init'方法)。而已。但编译后我有以下异常:

An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll

Additional information: Could not load file or assembly 'WrapperCLR.dll' or one of its dependencies. The specified module could not be found.

似乎找不到WrapperCLR.dll,但事实并非如此。实际上,如果我在'TargetDisplay.cpp'文件中删除所有SDL系统调用,程序编译,执行工作。

但当然没有显示,因为SDL系统调用被禁用。所以WrapperCLR.dll是由系统发现的。所以我想知道它是否找不到SDL2.dll库。

也许不可能通过C ++ CLR包装器从C#应用程序加载SDL C ++程序作为静态库?或者我可能需要在源代码中直接在汇编文件中添加链接的特定信息。

c# c++ sdl wrapper
1个回答
1
投票

我认为这只是你所说的单个DLL路径的问题。

在Visual Studio中的IIRC,默认情况下启动项目,当前当前目录设置为$(ProjectDir)并从$(OutDir)\$(Configuration)执行。

确保在这些目录中为顶级C#项目安装了WrapperCLR.dll和SDL2.dll。

它禁用对DLL的所有调用,因为它完全删除了导入(优化)。

© www.soinside.com 2019 - 2024. All rights reserved.