Цель моего приложения — загрузить простое окно SDL из приложения C # через оболочку C ++ CLR. Для выполнения работы я создал 3 проекта:
Библиотека 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();
}
Как вы можете видеть, я связал свою статическую библиотеку C ++ в своем проекте CLR и вызываю все методы (для информации, если я скомпилирую проект 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’. Может быть, невозможно загрузить программу SDL C ++ как статическую библиотеку из приложения C # через оболочку C ++ CLR? Или, может быть, мне нужно добавить конкретную информацию о связи в файле сборки или непосредственно в моем исходном коде. Я действительно потерян.
Кто-нибудь может мне помочь, пожалуйста?
Заранее большое спасибо за вашу помощь.
Я думаю, что это просто проблема с путями к отдельным DLL, как вы сказали.
IIRC в Visual Studio, проекты по умолчанию запускаются с текущим текущим каталогом $(ProjectDir)
и выполнен из $(OutDir)\$(Configuration)
,
Убедитесь, что у вас есть WrapperCLR.dll а также SDL2.dll в этих каталогах для верхнего уровня, C # проекта.
Он работает, когда вы отключаете все вызовы DLL, потому что тогда его импорт полностью удаляется (оптимизация).
Других решений пока нет …