This question already has an answer here:
Receive an array of string from a c++ DLL in Delphi 7
(1 answer)
Closed 7 years ago.
How can I return a string array from C++ dll and then the function will be call by a Delphi application.
I tried:
C++ dll
#include <windows.h>
#include <vector>
#include <string>
using namespace std;
extern "C"
{
__declspec( dllexport ) void arrayStr(vector<string> s)
{
s.push_back("111");
s.push_back("222");
s.push_back("333");
}
}
Delphi
procedure arrayStr(StrMem : TStringList); cdecl; external 'arrayStr.dll';
...
var
StrMem : TStringList;
i : integer;
begin
StrMem := TStringList.Create;
arrayStr(StrMem);
for i := 0 to StrMem.Count-1 do
begin
ShowMessage(StrMem[i]);
end;
StrMem.Free;
end;
The TStringList (Delphi) is incompatible with C++ STL containers.
You should do the following:
C/C++ side:
void __stdcall Func(char **strings, int count);
Delphi side:
type PPAnsiChar = ^PAnsiChar;
procedure Func(ArrayOfStrings: PPAnsiChar; CountOfArray: Integer); stdcall;
Related
I got an error from DLL that compiled from Delphi using in c++ run in multithread
Delphi (Architect 10.3 Version 26.0.32429.4364) Library Code
library Project1;
uses
System.SysUtils,
System.Classes;
{$R *.res}
procedure __test(size: integer); cdecl;
var
data : AnsiString;
begin
SetLength(data, size);
end;
exports
__test;
begin
end.
C++ (Viausl Studio 2019) Load Library And Using Multithread
// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <Windows.h>
#include <thread>
typedef void(__cdecl *functest)(int);
HINSTANCE hInst = nullptr;
functest test;
void thread_loop() {
while (1) {
test(10);
}
}
int main()
{
hInst = LoadLibraryA("Project1.dll");
if (!hInst) {
return 0;
}
test = (functest)GetProcAddress(hInst, "__test");
if (!test) {
return 0;
}
std::thread t1(thread_loop);
std::thread t2(thread_loop);
return 1;
I got an exception but it should not get any exception because that is procedure variable which was not shared
Set IsMultiThread to True in your Delphi DLL's main block. Delphi's default memory manager assumes single-threaded mode by default.
begin
IsMultiThread := True;
end.
I try to call a function from a dll, but it doesn't seem to work fine. Here is the code:
HMODULE dllhandle;
#include "Unit1.h"
#include <windows.h>
#include <iostream.h>
#include <conio.h>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
dllhandle = LoadLibrary((wchar_t*)"PBusDrv.dll");
if(dllhandle)
{
typedef int (*PBUSCONNECTEX)(String aux1, String aux2, String ip);
PBUSCONNECTEX PBusConnectEx;
PBusConnectEx = (PBUSCONNECTEX)GetProcAddress(dllhandle, "PBusConnectEx");
PBusConnectEx(" "," ","192.168.30.252");
}
}
dllhandle keeps returning with a null value.
The problem is probably here:
(wchar_t*)"PBusDrv.dll"
You are casting an ANSI string (1 byte per char) as a wide-string (2 bytes per char). This is never going to work.
You have 3 options:
1- Use the ANSI version of the LoadLibrary function
dllhandle = LoadLibraryA("PBusDrv.dll");
2- Use the appropriate string type according to the project configuration:
dllhandle = LoadLibrary(_T("PBusDrv.dll"));
3- Use the wide-string version of LoadLibrary, while passing a wide-string as input
dllhandle = LoadLibraryW(L"PBusDrv.dll");
Note: Don't mix non-specific function macros with one particular type of string. For example, don't do this:
dllhandle = LoadLibrary(L"PBusDrv.dll");
I want to load a fortran dll in C++ code and call a function in the fortran dll.
Following is the code
SUBROUTINE SUB1()
PRINT *, 'I am a function '
END
After creation of the foo.dll [fotran dll ] this is the folowing C++ code in visual studio 2012 that I have written to load the fortran dll .
and call the function SUB1 in the fortran code
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
extern "C" void SUB1();
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
int main(void)
{
LoadLibrary(L"foo.dll");
PGNSI pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("foo.dll")),"SUB1");
return 0;
}
While running the I am getting the following error:
The program can't start because libgcc_s_dw2-1.dll is missing from your computer.
Try reinstalling the program to fix this problem.
Is this the correct way of calling the dll from C++ ?
I am very new to this fortran dll . Please help me regarding this.
First of all you need to export the function like this...
!fortcall.f90
subroutine Dll1() BIND(C,NAME="Dll1")
implicit none
!DEC$ ATTRIBUTES DLLEXPORT :: Dll1
PRINT *, 'I am a function'
return
end !subroutine Dll1
Create the dll using following command
gfortran.exe -c fortcall.f90
gfortran.exe -shared -static -o foo.dll fortcall.o
After that, place the libgcc_s_dw2-1.dll, libgfortran-3.dll and libquadmath-0.dll in the application path of VS. OR you can add the PATH to environment.
After that, you can call the FORTRAN exposed function from VS like below...
#include <iostream>
#include <Windows.h>
using namespace std;
extern "C" void Dll1();
typedef void(* LPFNDLLFUNC1)();
int main(void)
{
HINSTANCE hDLL;
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
hDLL = LoadLibrary(L"foo.dll");
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,"Dll1");
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
return -1;
}
else
{
// call the function
lpfnDllFunc1();
}
}
return 0;
}
I want to call a c++ function from my vb.net project and i'm trying to create a dll to do so.I've never tried it before so according to the guides i read i created a dll.dll(using C++ in Visual Studio) with a dll.def file and i tried linking it to my VB project. Athough i can build it without any error it crushes and i get
'System.Runtime.InteropServices.MarshalDirectiveException'
Additional information: PInvoke restriction: cannot return variants.
My code is this:
dll.h
#define WDL_API __declspec(dllexport)
extern "C" WDL_API int __stdcall wdl(void);
dll.cpp
#include "stdafx.h"
#include "dll.h"
#include <stdio.h>
#include <windows.h>
char var[] = {"a"};
extern "C" WDL_API int __stdcall wdl(void)
{
int i, len1 = sizeof(var);
char sName[100], sAns[10];
FILE *ptr;
errno_t errorCode = fopen_s(&ptr, ".\\file", "wb");
for (i = 0; i<len1 - 1; i++)
fprintf(ptr, "%c", var[i]);
fclose(ptr);
return 0;
}
dll.def
LIBRARY dll
EXPORTS
wdl #1
vbproject
Module Module1
Public Declare Auto Function wdl _
Lib "dll.dll" Alias "wdl" ()
Sub Main()
Console.WriteLine("inside vb.net")
wdl()
End Sub
End Module
The code seems to make sense but i can't find out if i am missing something or there are mistakes of some kind.Any help would be much appreciated!
You did not specify the return type and so VB assumes that it is a variant. You don't want that. It is a C int, or VB Integer. Code it like this:
Public Declare Auto Function wdl Lib "dll.dll" Alias "wdl" () As Integer
That said, pinvoke is to be preferred over Declare these days so I would write it like this:
<DllImport("dll.dll")> _
Public Shared Function wdl() As Integer
End Function
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
std::string in C#?
How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#?
Is there a way to convert from a c++ std:string to C# System.String? I'm calling a function from a C++ dll that takes a std:string as input. Is there a simple way to do this?
C#:
[DllImport(#"MyDLL.dll")]
[return:MarshalAs(UnmanagedType.I1)]
public static extern bool myFunction([In, Out]string input);
C++:
extern "C" __declspec(dllexport) BOOL __stdcall myFunction(const std::string& input)
{
//Code is here
}