C# DLL中的CreateWindowEx()创建一个标题为奇数的窗口
谢谢你花了这么多时间来回答这个问题 我试图创建一个DLL,从DLL中打开一个窗口。我正在用C#运行创建的DLL。DLL是在VSC中创建的,C代码是用VSC编译的 该窗口是通过调用C#中的C# DLL中的CreateWindowEx()创建一个标题为奇数的窗口,c#,c++,windows,string,dll,C#,C++,Windows,String,Dll,谢谢你花了这么多时间来回答这个问题 我试图创建一个DLL,从DLL中打开一个窗口。我正在用C#运行创建的DLL。DLL是在VSC中创建的,C代码是用VSC编译的 该窗口是通过调用C#中的Initalize(const char*title)或Initalize(string title)来实现的。不管我怎么做,创建的窗口是创建的,运行的,但它的标题不是传递的字符串。我尝试过使用const wchar\u t*,LPCSTR,LPCWSTR,System.String,[MarshalAs(Unm
Initalize(const char*title)
或Initalize(string title)
来实现的。不管我怎么做,创建的窗口是创建的,运行的,但它的标题不是传递的字符串。我尝试过使用const wchar\u t*
,LPCSTR
,LPCWSTR
,System.String
,[MarshalAs(UnmanagedType.LPStr)]
,[MarshalAs(UnmanagedType.LPWStr)]
。我尝试将传递的字符串复制到一个动态分配的数组中,该数组使用new/delete和malloc/free进行分配
我认为这是一个指针错误,但最让我想到的是,
// GameInterface.cpp : Defines the exported functions for the DLL application.
//
#include "GameInterface.h"
#include <Windows.h>
// OpenGL was origionally implimented into here, and removed to be asked on StackOverflow.
LRESULT WINAPI DLLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance = NULL;
ATOM wclAtom = NULL;
HWND hWnd = NULL;
HDC hDC = NULL;
HGLRC hRC = NULL;
bool running = false;
#if _DEBUG
#include <stdio.h>
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
#if _DEBUG
printf("GameInterface.dll::DllMain()\n");
#endif
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
hInstance = hModule;
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
Shutdown();
break;
}
return TRUE;
}
GAMEINTERFACE_API int Initalize(const char* title)
{
if (hWnd != NULL)
return 0;
#if _DEBUG
printf("GameInterface.dll::Initalize(\"%s\")\n", title);
#endif
int length = strlen(title);
char* name = new char[length+1];
strcpy(name, title);
WNDCLASSEXA wcl;
wcl.cbSize = sizeof(WNDCLASSEXA);
wcl.style = CS_OWNDC;
wcl.lpfnWndProc = DLLWindowProc;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hInstance = hInstance;
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
wcl.lpszMenuName = NULL;
wcl.lpszClassName = name;
wcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wclAtom = RegisterClassExA(&wcl);
#if _DEBUG
printf(" Registering Class\n");
#endif
if (!wclAtom)
{
#if _DEBUG
printf(" Error: Could not Register Class.\nExiting with error: %i\n", GetLastError() );
#endif
return 1;
}
#if _DEBUG
printf(" Creating Window\n");
#endif
hWnd = CreateWindowExA(0,
(LPCSTR)wclAtom,
(LPCSTR)name,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
512, 512,
NULL, NULL,
hInstance, NULL);
if (hWnd == NULL)
{
#if _DEBUG
printf(" Error: Window could not be created.\nExiting with error: %i\n", GetLastError() );
#endif
return 2;
}
#if _DEBUG
printf(" Displaying Window\n");
#endif
// to reduce size removed the code to initalize an OpenGL 3.1 context
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
running = true;
delete [] name;
#if _DEBUG
printf("Returning from GameInterface.dll::Initalize(const char*) with errors: %i\n", GetLastError() );
#endif
return 0;
}
GAMEINTERFACE_API void Shutdown()
{
if (running = false)
return;
#if _DEBUG
printf("GameInterface.dll::Shutdown()\n");
#endif
running = false;
wglMakeCurrent(NULL, NULL);
if (hRC != NULL) wglDeleteContext(hRC);
if (hDC != NULL) ReleaseDC(hWnd, hDC);
hRC = NULL;
hDC = NULL;
DestroyWindow(hWnd);
UnregisterClassA( (LPCSTR)wclAtom, hInstance);
wclAtom = NULL;
hWnd = NULL;
running = false;
}
GAMEINTERFACE_API int Update()
{
if ( (running == false) && (hWnd == NULL) )
return 1;
MSG msg;
if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (running == false)
return 1;
return 0;
}
GAMEINTERFACE_API void DrawFrame()
{
// Contained some OpenGL code that has now been removed.
}
LRESULT WINAPI DLLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
running = false;
break;
// handle other messages.
default: // anything we dont handle.
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0; // just in case
}
// GameInterface.h : Outlines the exported functions for the DLL application.
//
#pragma once
#ifdef GAMEINTERFACE_EXPORTS
#define GAMEINTERFACE_API __declspec(dllexport)
#else
#define GAMEINTERFACE_API __declspec(dllimport)
#endif
extern "C"
{
GAMEINTERFACE_API int Initalize(const char* title);
GAMEINTERFACE_API void Shutdown();
GAMEINTERFACE_API int Update();
GAMEINTERFACE_API void DrawFrame();
};
我已经难受了,已经有一段时间了。
你在C++的构建中定义了<代码> Unicode < /Code >和 Unicode < /Code >吗?你需要这样,C#才能那样跟它说话
在C++项目的VisualStudio属性中,在>Nuth/Stult>下,设置“强”字符集 >强> >使用Unicode字符集>。再次检查
/D“UNICODE”
和/D“\u UNICODE”
是否出现在C/C++/命令行页面上
< P>(相反的方法是声明出口为ANSI,但这是一个更差的解决方案。您应该支持Unicode)。< /P> < P>您在C++构建中定义了<代码> Unicode < /Code >和 Unicode < /Code >吗?你需要这样,C#才能那样跟它说话
在C++项目的VisualStudio属性中,在>Nuth/Stult>下,设置“强”字符集 >强> >使用Unicode字符集>。再次检查
/D“UNICODE”
和/D“\u UNICODE”
是否出现在C/C++/命令行页面上
(相反的方法是将导出声明为ANSI,但这是一个较差的解决方案。您应该支持Unicode。)这可能是因为代码需要ANSI
如果您尝试以下操作,会发生什么情况:
[DllImport(GameInterfaceFile, CharSet=CharSet.Ansi)] public extern static int Initalize(string title)
这可能是因为代码需要ANSI
如果您尝试以下操作,会发生什么情况:
[DllImport(GameInterfaceFile, CharSet=CharSet.Ansi)] public extern static int Initalize(string title)
Unicode是我能想到的第一件事。也许标题是LPWSTR/LPCWSTRUnicode是我能想到的第一件事。也许标题是LPWSTR/LPCWSTRYou接近了。在有定义的地方奴役他们并没有做到这一点,但在没有定义的地方奴役他们做到了这一点。谢谢你接近了。在有定义的地方奴役他们并没有做到这一点,但在没有定义的地方奴役他们做到了这一点。谢谢我还是犯了错误。但是谢谢你的帮助!这使我走上了正确的道路,我仍然犯了错误。但是谢谢你的帮助!这使我走上了正确的道路。