Calling a function from a FORTRAN DLL using C++ code - c++

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;
}

Related

Error using library functions of cygwin compiled dll in visual studio

I am trying to call cygwin compiled dll in wisual studio environment.
If I compile dll which have function without any library (just return any number),
it works ok, but if I call for example stdio.h, and function with writing file, or just printf function, does not work ( in case of printf function has exited with code 1536).
#include <stdio.h>
int myfunc()
{
char* strtxt = "test";
FILE *hF = fopen( "Newlogtst.txt", "w" );
if(hF == 0)
{
return 5;
}
fputs( (const char*)strtxt, hF );
fclose(hF);
return 1;
}
int tst()
{
return 25;
}
function tst works ok, function myfunc make empty file Newlogtst.txt and shows exception .
`
Exception thrown at 0x6113333A (cygwin1.dll) in CygwinDlltest.exe:
0xC0000005: Access violation reading location 0x004E0059.
If there is a handler for this exception, the program may be safely
continued.
`
in visual studio I am using this code
#include <windows.h>
typedef int (*PFN_HELLO)();
typedef void (*PFN_CYGWIN_DLL_INIT)();
int main()
{
PFN_HELLO func;
HMODULE hLib, h = LoadLibrary(TEXT("C:\\cygwin\\bin\\cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT) GetProcAddress(h,"cygwin_dll_init");
init();
hLib = LoadLibrary (TEXT("C:\\Cygwin\\home\\azatyan\\TestDynamicLink\\mydll.dll"));
func = (PFN_HELLO) GetProcAddress (hLib, "myfunc");
return func();
}
please help what should I do to use library functions.
You don't check the returncode of GetProcAddress().
If you compile it in C++, the names are mangled differently, (which is why GetprocAddress() will return NULL btw.) because they are different compilers.
If you are just using basic functions like in your example, you should declare them as extern "C" so that they wont get mangled. Also make sure that the __declspec export statement are used correctly when compiling the DLL.

lnk1136 - invalid or corrupt .lib

I've got a little problem. I got a dll C library, a header file, and all other files needed to call this dll. I've tried calling this dll through third party programs and it is working.
However, when I try calling it directly (dynamic linking at load and using the given header file) I always get the linker error 1136 with mydll.lib.
Using the header file:
#include "windows.h"
#include "mydll.h"
void main() {
bool test;
test = CallDll("MyArg");
}
With code in headerfile as below:
extern "C" bool _stdcall CallDll(char* MyArg);
Using dynamic linking at load time:
#include "windows.h"
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary((LPCSTR)"mydll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll("MyArg");
}
Now what did I do wrong? I doubt the mydll.lib file is broken, because if this were the issue, I couldn't access the dll with a third party program.
Well it was a rather simple solution.
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary(L"mydll.dll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll((char*)"MyArg");
}
Was all it needed...

Cannot use c++ dll in vb.net project

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

call dll in a c++ file

I created a DLL file (helloWorld.dll):
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define DLL_FUNC extern "C" __declspec(dllexport)
DLL_FUNC int __stdcall Hello() {
MessageBox(HWND_DESKTOP, "Hello, world", "MEssage", MB_OK);
return 0;
}
After that I created a cpp where I would like to call (useDLL.cpp)
#include <windows.h>
#include <stdio.h>
int main () {
typedef void (*pfunc)();
HINSTANCE hdll = LoadLibrary("HelloWorld.dll");
pfunc Hello;
Hello = (pfunc)GetProcAddress(hdll, "hello");
Hello();
return 0;
}
How can I call the Hello() function?
The code in the question contains a number of errors:
LoadLibrary returns HMODULE and not HINSTANCE
The function pointer has the wrong return value and an incorrect calling convention.
Function names are case sensitive and you must account for name decoration.
You did no error checking at all. Your code probably fails on the call to GetProcAddress, returns NULL and then bombs when you try to call the function at NULL.
So you need something like this:
typedef int (__stdcall *HelloProc)();
....
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if (hdll == NULL)
// handle error
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "_Hello#0");
if (Hello == NULL)
// handle error
int retval = Hello();
The function name is decorated because you used __stdcall. If you had used __cdecl, or a .def file, then there would have been no decoration. I'm assuming MSVC decoration. It seems that decoration differs with your compiler, mingw, and the function is named "Hello#0".
Frankly it's much easier to do it with a .lib file instead of calling LoadLibrary and GetProcAddress. If you can, I'd switch to that way now.
You need to specifically search and find specific functions you are lookins for, check out this link:
Calling functions in a DLL from C++

Using a dll in C++ code

I want to use pjsipDll.dll in a c++ code. I got this dll from one of the sites, I only know how to build the code to obtain the dll file. So I did that and now I've the pjsipDll.dll file with me. I want to use certain functions in the DLL in my code(C++)
I tried the following code. << I haven't made/added any dll or .h file to the project, there is only the following CPP file>>
#include <iostream>
using namespace std;
int CallMyDLL(void)
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("G:\\July\\9.0\\pjsipdll\\Lib\\pjsipDll.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"dll_makeCall");
/*
Define the Function in the DLL for reuse. This is just prototyping the dll's function.
A mock of it. Use "stdcall" for maximum compatibility.
*/
typedef int (__stdcall * pICFUNC)(int, char *);
pICFUNC MyFunction;
MyFunction = pICFUNC(lpfnGetProcessID);
/* The actual call to the function contained in the dll */
int intMyReturnVal = MyFunction(5,"hello");
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
/* The return val from the dll */
returnintMyReturnVal;
}
void main()
{
cout<<"Hello World";
CallMyDLL();
getchar();
}
I learnt this way from some site, to use the function from a DLL.
The problem is, I get an ERROR:
error C2065: 'HINSTANCE' : undeclared identifier g:\july\9.0\pjproject-0.9.0\myproject\importerprojet\importerprojet\mycpp.cpp 9 importerProjet
Can anyone help me out with this. Or atleast point me to the post if this query is already addressed.
Thanks for your help,
Vinu.
You need to #include <windows.h>