Miha Bogataj
Miha Bogataj

Reputation: 439

Using VS C++ functions in Inno Setup

I'm trying to replace some functions made in LazarusLib with functions written in C++ for Inno Setup installer.

So I created a Dynamic-Link Library (DLL) project in Visual studio and added the following code:

InstallerFunctions.h:

extern "C" {
    __declspec(dllexport) bool __stdcall CheckPortAvailable(int Port);
}

InstallerFunctions.cpp:

#include "pch.h"
#include "framework.h"
#include "InstallerFunctions.h"
#include <windows.h>
#include <winsock.h>
#include <string>
#include <fstream>

bool __stdcall CheckPortAvailable(int Port) {
    WSADATA WSAData;
    SOCKET Sock;
    sockaddr_in SockAddr;
    int ErrorCode;

    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
        return false;

    Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Sock == INVALID_SOCKET)
        return false;

    ZeroMemory(&SockAddr, sizeof(SockAddr));
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = INADDR_ANY;
    SockAddr.sin_port = htons(Port);

    ErrorCode = bind(Sock, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr));
    closesocket(Sock);

    WSACleanup();

    return (ErrorCode != SOCKET_ERROR);
}

This project builds successfully. The project is configured to output the DLL file to \Output\
Then I added this to Inno Setup script:

[Files]
Source: "..\InstallerFunctions\Output\InstallerFunctions.dll"; DestDir: "{app}"; Flags: ignoreversion

The path is correct. Then I declare the function as following:

function CheckPortAvailable(Port: Integer): Boolean;
external 'CheckPortAvailable@files:InstallerFunctions.dll stdcall delayload';

When I try to call CheckPortAvailable I get the following error:

Could not call proc.

I tried to use DLL explorer to find the functions I require and DLL explorers are able to find the functions. Any idea what else can I try?

It appears that the function is recognized, so the issue definitely lies in C++ project:

Upvotes: 1

Views: 118

Answers (2)

Miha Bogataj
Miha Bogataj

Reputation: 439

It seems that the main issue is that the function name is different than expected:

enter image description here

The upper part is from LazarusLib (CheckPortAvailable), the lower part is from Visual Studio C++ project (_CheckPortAvailable@4).


The solution was to create a .def file with the following content:

LIBRARY InstallerFunctions
EXPORTS
    CheckPortAvailable

and specify it in Linker > Input > Module Definition File.

Upvotes: 1

Slappy
Slappy

Reputation: 5472

My guess is that your .dll file is not present on machine at the time you call the exported function from it.

[Files] section is processed when Install page is shown (that is when installer is processing the section and copying the files and so one).

I suppose you are calling your .dll function earlier, so solution for you might be to extract the .dll into the Temp folder at installer startup so the exported fucntion is available.

Upvotes: -1

Related Questions