C# DLL中的CreateWindowEx()创建一个标题为奇数的窗口

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

谢谢你花了这么多时间来回答这个问题

我试图创建一个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(UnmanagedType.LPStr)]
[MarshalAs(UnmanagedType.LPWStr)]
。我尝试将传递的字符串复制到一个动态分配的数组中,该数组使用new/delete和malloc/free进行分配

我认为这是一个指针错误,但最让我想到的是, > PrTTF(“通过字符串:%s”,title)<代码>在我的C++代码中打印正确的标题到控制台,但是我的窗口看起来像:

<>我的C++代码是:

// 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接近了。在有定义的地方奴役他们并没有做到这一点,但在没有定义的地方奴役他们做到了这一点。谢谢你接近了。在有定义的地方奴役他们并没有做到这一点,但在没有定义的地方奴役他们做到了这一点。谢谢我还是犯了错误。但是谢谢你的帮助!这使我走上了正确的道路,我仍然犯了错误。但是谢谢你的帮助!这使我走上了正确的道路。