I am currently trying to use my DirectX C++ engine in a C# project to develop a level editor. Based on the advice I was given I have decided to write my engine in a DLL and use p/invoke in C#. http://gamedev.stackexchange.com/questions/124249/how-do-i-render-my-directx-c-engine-to-a-c-panel
An unhandled exception of type 'System.BadImageFormatException' occurred in DirectXinForms.exe
I don't know what the problem is but can someone help me fix this? Maybe there's an issue with the DLL aswell. Here is my code for the C++ DLL & C# Windows Forms project. I am also unable to directly add a reference to the DLL in C# but using
[DLLImport]
seemed to work.
DLL Header.h
#pragma once
#define DllExport __declspec(dllexport)
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include <DirectXMath.h>
using namespace DirectX;
// include the Direct3D Library file
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
// global declarations
IDXGISwapChain *swapchain; // the pointer to the swap chain interface
ID3D11Device *dev; // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context
ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer
extern "C"
{
__declspec(dllexport) void InitD3D(HWND hWnd, int Width, int Height); // sets up and initializes Direct3D
}
extern "C"
{
__declspec(dllexport) void RenderFrame(void); // renders a single frame
}
extern "C"
{
__declspec(dllexport) void CleanD3D(void); // closes Direct3D and releases memory
}
DLL Main.cpp
#include "Header.h"
void InitD3D(HWND hWnd, int Width, int Height)
{
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
HRESULT hr = S_OK;
// fill the swap chain description struct
scd.BufferCount = 2; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 8; // how many multisamples
scd.SampleDesc.Quality = 1;
scd.Windowed = TRUE;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching// windowed/full-screen mode
// create a device, device context and swap chain using the information in the scd struct
hr = D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon);
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
pBackBuffer->Release();
// set the render target as the back buffer
devcon->OMSetRenderTargets(1, &backbuffer, NULL);
// Set the viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = Width;
viewport.Height = Width;
devcon->RSSetViewports(1, &viewport);
}
void RenderFrame(void)
{
// clear the back buffer to a deep blue
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
// do 3D rendering on the back buffer here
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}
void CleanD3D(void)
{
// close and release all existing COM objects
swapchain->Release();
backbuffer->Release();
dev->Release();
devcon->Release();
}
C# Project:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DirectXinForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Dengine.Initialize(panel1.Handle, panel1.Width, panel1.Height);
Dengine.RenderFrame();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Dengine.CleanD3D();
}
}
public class Dengine
{
[DllImport("DirectXENGINEDLL.dll")]
public static extern void Initialize(IntPtr window, int Width, int Height);
[DllImport("DirectXENGINEDLL.dll")]
public static extern void RenderFrame();
[DllImport("DirectXENGINEDLL.dll")]
public static extern void CleanD3D();
}
}