我制作了一个使用对话框录制和播放的win32 DLL。我试图在我的C#代码中使用它,通过一个函数传入一个指针,这样我就可以保存数据并实际上让对话框打开另一个函数调用CreateDialog并给它我的DLGPROC。我想让dll尽可能独立运行,只保留对数据的引用并告诉它何时打开和关闭。
Header.h:
#pragma once
#pragma comment(lib, "winmm.lib")
#include <Windows.h>
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT BOOLEAN StartDiag();
EXPORT BOOLEAN SetData(DOUBLE*);
Record.c:
#include <windows.h>
#include "resource.h"
#include "Header.h"
#define INP_BUFFER_SIZE 16384
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT("Record1");
double* pData;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
return 0;
}
BOOLEAN StartDiag()
{
if (CreateDialog(NULL, MAKEINTRESOURCE(DLG_RECORD), NULL, DlgProc) ==
NULL)
{
return FALSE;
}
return TRUE;
}
BOOLEAN SetData(double* p)
{
p = pData;
return TRUE;
}
BOOL CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
}
C#:
[DllImport("RecordLib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern Boolean SetData(ref double[] d);
[DllImport("RecordLib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern Boolean StartDiag();
我非常有信心正确调用StartDiag,因为它总是返回false,这意味着输入了函数体,并正确评估了if语句。显而易见的问题是这意味着DLL不会像我想要的那样创建一个对话框。 Dialog显然是在一个rc文件中,应该包含在dll中,所以它是如何工作的?我如何让我的DLL实际运行对话框资源?
答案 0 :(得分:0)
if (CreateDialog(NULL, ...)
你不能在这里传递NULL并希望成功。这只适用于简单的单模块程序,这种程序只包含一个包含所有内容的EXE文件。在您的方案中,Windows将在托管程序集中搜索资源。那是一只失败的鲸鱼。它必须是包含对话框资源的模块的句柄。当然是DLL。
你需要DllMain()而不是WinMain()。存放您获得的手柄,以便以后使用。样板:
HMODULE ThisDllHandle;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID)
{
if (reason == DLL_PROCESS_ATTACH) {
ThisDllHandle = hModule;
DisableThreadLibraryCalls(hModule);
}
return TRUE;
}