Есть WPF проект на C# и С++ dll реализующая некоторые сложные вычисления, возможно ли как то подключить эту библиотеку к С# проекту для создания экземпляров классов С++, и если да, то что для этого требуется? Если не сложно объясните поэтапно, я в этом деле новичок.
Если вы хотите использовать именно классы c++
, то вариант решения, примерно такой:
generic
классом:public abstract class CClassBase<TNewDelegate, TDeleteDelegate> :
IDisposable
where TNewDelegate : Delegate
where TDeleteDelegate : Delegate
{
protected TNewDelegate New;
protected TDeleteDelegate Delete;
protected IntPtr ThisPtr;
protected CClassBase(TNewDelegate newDelegate, TDeleteDelegate deleteDelegate)
{
New = newDelegate;
Delete = deleteDelegate;
}
public bool IsDisposed
{
get;
protected set;
}
protected abstract void Dispose(bool disposable);
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~CClassBase()
{
Dispose(false);
}
}
generic
:// Делегат конструктора без параметров, вы можете определять свои, и наследоваться от generic класса
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
public delegate void NewDelegate(ref IntPtr thisPtr);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
public delegate void DeleteDelegate(ref IntPtr thisPtr);
public class CClassBase :
CClassBase<NewDelegate, DeleteDelegate>
{
protected CClassBase(NewDelegate newDelegate, DeleteDelegate deleteDelegate)
: base(newDelegate, deleteDelegate)
{
New(ref ThisPtr);
}
protected override void Dispose(bool disposable)
{
if (IsDisposed)
{
return;
}
Delete(ref ThisPtr);
if (disposable)
{
ThisPtr = IntPtr.Zero;
New = null;
Delete = null;
}
IsDisposed = true;
}
}
В моем случае неуправляемый класс объявлен как:
struct MI_CORE_API engine : public ::window_container
{
public:
::LRESULT on_message(::HWND hwnd, ::UINT msg, ::WPARAM w_param, ::LPARAM l_param) override;
bool process_messages() override;
bool initialize(::HINSTANCE app_instance, ::int32_t width, ::int32_t height, wchar_t const* application_name);
};
Соответственно я определил управляемый класс как:
public class Engine :
CClassBase
{
[DllImport("mi_core.dll",
CallingConvention = CallingConvention.ThisCall,
EntryPoint = "??0engine@@QAE@XZ")]
private static extern void EngineNew(ref IntPtr thisPtr);
[DllImport("mi_core.dll",
CallingConvention = CallingConvention.ThisCall,
EntryPoint = "??1engine@@UAE@XZ")]
private static extern void EngineDelete(ref IntPtr ptr);
[DllImport("mi_core.dll",
CallingConvention = CallingConvention.ThisCall,
EntryPoint = "?initialize@engine@@QAE_NPAUHINSTANCE__@@HHPB_W@Z")]
private static extern bool EngineInitialize(ref IntPtr thisPtr, IntPtr applicationInstance, int width, int height,
[MarshalAs(UnmanagedType.LPWStr)] string applicationName);
[DllImport("mi_core.dll",
CallingConvention = CallingConvention.ThisCall,
EntryPoint = "?process_messages@engine@@UAE_NXZ")]
private static extern bool EngineProcessMessages(ref IntPtr thisPtr);
public Engine() :
base(EngineNew, EngineDelete)
{
GC.KeepAlive(this);
}
public bool ProcessMessages()
{
return EngineProcessMessages(ref ThisPtr);
}
public bool Initialize(int width, int height, string applicationName)
{
ProcessModule processModule = Process.GetCurrentProcess().MainModule;
if (processModule == null)
{
return false;
}
IntPtr applicationInstance = processModule.BaseAddress;
return EngineInitialize(ref ThisPtr, applicationInstance, width, height, applicationName);
}
}
Ну и запуск:
internal static class Program
{
public static int Main(string[] args)
{
using (Engine engine = new Engine())
{
if (!engine.Initialize(1280, 720, "Some Application Name"))
{
return 1;
}
while (engine.ProcessMessages())
{
}
}
return 0;
}
}
Результат:
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Почему я не могу так сделать? У меня два селектаПервый солект должен создать вложенный объект у объекта Album
Необходимо сделать так, что бы при смерти моего главного героя на этом месте появлялся объект - его душаПочему то в данный момент получается...
После ошибки "Пакет Shared Web Component не был правильно загружен" удалил Visual Studio Community 17 и установил Visual Studio Community 19
Пытаюсь получить значение после определенного текста в html коде страницыpage