编写C扩展
exdll.c
c
#include <windows.h>
#include <nsis/pluginapi.h> // nsis plugin
#pragma
HINSTANCE g_hInstance;
HWND g_hwndParent;
typedef void (*HELLO_FUNC)();
// To work with Unicode version of NSIS, please use TCHAR-type
// functions for accessing the variables and the stack.
void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
LPTSTR variables, stack_t **stacktop,
extra_parameters *extra, ...)
{
//初始化很重要
EXDLL_INIT();
g_hwndParent = hwndParent;
// do your stuff here
{
LPTSTR msgbuf = (LPTSTR) GlobalAlloc(GPTR, (3 + string_size + 1) * sizeof(*msgbuf));
if (msgbuf)
{
wsprintf(msgbuf, TEXT("$0=%s"), getuservariable(INST_0));
MessageBox(g_hwndParent, msgbuf, TEXT("Message from example plugin"), MB_OK);
GlobalFree(msgbuf);
}
}
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance = hInst;
return TRUE;
}
调用侧:
cpp
; rtest.nsi
;
; This script tests some advanced NSIS functions.
;--------------------------------
Name "rtest"
OutFile "rtest.exe"
ComponentText "Select tests!"
ShowInstDetails show
RequestExecutionLevel user
;--------------------------------
Section "Test MyPlugin"
StrCpy $0 "file.dat"
StrCpy $1 "read.txt"
exdll::myFunction
SectionEnd
由于NSIS默认是不支持C++扩展的,因此可以采用动态加载dll的方式;
编写C++功能的dll
注意这里的extern C
cpp
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <iostream>
#include <fstream>
extern "C" __declspec(dllexport) void hello_cpp() {
std::ofstream outFile("output.txt", std::ios::out);
if (!outFile) {
std::cerr << "Unable open file!" << std::endl;
return;
}
outFile << "Hello from C++!" << std::endl;
outFile.close();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
编译为dll后在C侧动态加载dll
c
#include <windows.h>
#include <nsis/pluginapi.h> // nsis plugin
#pragma
HINSTANCE g_hInstance;
HWND g_hwndParent;
typedef void (*HELLO_FUNC)();
// To work with Unicode version of NSIS, please use TCHAR-type
// functions for accessing the variables and the stack.
void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
LPTSTR variables, stack_t **stacktop,
extra_parameters *extra, ...)
{
EXDLL_INIT();
g_hwndParent = hwndParent;
HMODULE hDll = LoadLibraryA("C:/Users/tians/Source/Repos/Dll1/Debug/Dll1.dll");
if (!hDll) {
return;
}
HELLO_FUNC hello = (HELLO_FUNC)GetProcAddress(hDll, "hello_cpp");
if (!hello) {
FreeLibrary(hDll);
return;
}
hello();
FreeLibrary(hDll);
// note if you want parameters from the stack, pop them off in order.
// i.e. if you are called via exdll::myFunction file.dat read.txt
// calling popstring() the first time would give you file.dat,
// and the second time would give you read.txt.
// you should empty the stack of your parameters, and ONLY your
// parameters.
// do your stuff here
{
LPTSTR msgbuf = (LPTSTR) GlobalAlloc(GPTR, (3 + string_size + 1) * sizeof(*msgbuf));
if (msgbuf)
{
wsprintf(msgbuf, TEXT("$0=%s"), getuservariable(INST_0));
MessageBox(g_hwndParent, msgbuf, TEXT("Message from example plugin"), MB_OK);
GlobalFree(msgbuf);
}
}
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance = hInst;
return TRUE;
}
这样就可以充分利用C++的特性了。