Error using library functions of cygwin compiled dll in visual studio - c++

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.

Related

why to mention not to mangle the name when calling a c++ function from other c++ dll

This is my exported function in dll1
extern"C" __declspec(dllexport) int FUN1(char* p){
return p[0];
}
I am calling this FUN1 from other project.Below is the code
#include
#include
using namespace std;
typedef int (*MYFUN1)(char*);
int main()
{
HMODULE hMod = LoadLibrary ("C:\\Users\\admin\\Documents\\Visual Studio 2010\\Projects\\CalledFun\\Debug\\CalledFun.exe");
if(hMod != NULL)
{
MYFUN1 pCtor = (MYFUN1) GetProcAddress (hMod, "FUN1");
int a = pCtor("calling a value") ;
cout<<a;
}
}
If I remove the extern "C" from dll1 then that function address is returning as NULL when calling GetProcAddress in dll2. Since both are written in c++ I thought name mangling will not effect this.I thought if we use c and c++ libraries combinely then only we need to mention extern "C" ,Can anyone help me to get out of this confusion
Thanks in advance
You need to disable name mangling because you are using Windows API like LoadLibrary to which you provide function name. Windows API an LoadLibrary in particular know nothing about your compiler name mangling, so you need to turn it off.

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

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

Calling Win32 DLL from C++

I am new to the DLL world. I have been given a Win32 DLL which has a lot of functions. Need to call these DLL functions from C++
I want to call CreateNewScanner which creates a new scanner object and get the results in C++.
Function mentioned in the DLL is:
BOOL CreateNewScanner(NewScanner *newScan);
and NewScanner is a struct, as below,
// Structure NewScanner is defined in "common.h" .
typedef struct{
BYTE host_no; // <- host_no =0
LONG time; // <- command timeout (in seconds)
BYTE status; // -> Host adapter status
HANDLE obj; // -> Object handle for the scanner
}NewScanner;
How will I call this function? Started with C++ and here is what I managed,
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
HINSTANCE hInstance;
if(!(hInstance=LoadLibrary("WinScanner.dll"))){
cout << "could not load library" << endl;
}
/* get pointer to the function in the dll*/
FARPROC handle = GetProcAddress(HMODULE(hInstance), "CreateNewScanner");
if(!handle){
// Handle the error
FreeLibrary(hInstance);
return "-1";
}else{
// Call the function
//How to call here??
}
}
First of all, return "-1" is no good. You are expected to return an integer. So you surely mean return -1.
Now to the question. Instead of declaring the function pointer as FARPROC, it's easier to declare it as a function pointer type.
typedef BOOL (*CreateNewScannerProc)(NewScanner*);
Then call GetProcAddress like this:
HMODULE hlib = LoadLibrary(...);
// LoadLibrary returns HMODULE and not HINSTANCE
// check hlib for NULL
CreateNewScannerProc CreateNewScanner =
(CreateNewScannerProc) GetProcAddress(hlib, "CreateNewScanner");
if (CreateNewScanner == NULL)
// handle error
// now we can call the function
NewScanner newScan;
BOOL retval = CreateNewScanner(&newScan);
Having said all of that, usually a library will come with a header file (yours clearly does so you should include it) and a .lib file for load-time linking. Make sure that you pass the .lib file to your linker and you can simply do this:
#include "NameOfTheHeaderFileGoesHere.h"
....
NewScanner newScan;
BOOL retval = CreateNewScanner(&newScan);
No need to mess around with LoadLibrary, GetProcAddress and so on.
If you want to follow the LoadLibrary/GetProcAddress/FreeLibrary approach, consider the following "code path" (note that if you have the DLL public header file and the corresponding .lib file, just #include the public DLL header, and link with the .lib file, and just use the function whose prototype is defined in the DLL header as you would do with an ordinary C function called from C++ code).
Define a typedef for a pointer to the function exported from the DLL.
Note that the calling convention is specified (usually, Win32 DLLs with pure-C interfaces use __stdcall calling convention):
//
// Prototype of the DLL function, with *calling convention* specified
// (usually it's __stdcall for DLL with pure-C interface).
//
typedef BOOL (__stdcall *CreateNewScannerPtr)(NewScanner *);
Then you try loading the DLL using LoadLibrary:
//
// Try loading the DLL.
//
HMODULE hDll = LoadLibrary(L"WinScanner.dll"); // <--- Note the use of L"..." for Unicode
if (! hDll)
{
.... error
}
Note that the file name of the DLL is a Unicode string (note the L"..." decoration). In general, you should use Unicode in modern C++/Win32 code.
Then you can try getting the function pointer using GetProcAddress:
//
// Try getting the pointer to CreateNewScanner DLL function.
//
auto pCreateNewScanner = reinterpret_cast<CreateNewScannerPtr>
(
GetProcAddress
(
hDll, // DLL handle
"CreateNewScanner" // Function name
)
);
if (! pCreateNewScanner)
{
.... error
// Release the DLL
FreeLibrary(hDll);
// Avoid dangling references
hDll = nullptr;
}
Note that since you are using C++, it's better using C++-style casts (like reinterpret_cast<> in this case), instead of old C-style casts.
Moreover, since the type of the function pointer is specified in reinterpret_cast, it's useless to repeat it at the beginning of the statement, so the new C++11's keyword auto can be used.
You can use the returned function pointer to call the DLL function:
BOOL retCode = pCreateNewScanner( .... );
// Note: some other common prefix used in this case is "pfn"
// as "pointer to function" (e.g. pfnCreateNewScanner).
Once you have finished using the DLL, you can release it, calling FreeLibrary:
//
// Release the DLL
//
FreeLibrary(hDll);
hDll = nullptr;
In addition, note that you can use the C++ RAII pattern, and define a class with a destructor that automatically frees the DLL (this simplifies the code that manages the library loading/releasing parts).
e.g.
class RaiiDll
{
public:
// Load the DLL.
explicit RaiiDll(const std::wstring& filename) // may also provide an overload
// with (const wchar_t*)
{
m_hDll = ::LoadLibrary(filename.c_str());
if (! m_hDll)
{
// Error
throw std::runtime_error("Can't load the DLL - LoadLibrary() failed.");
// .... or use some other exception...
}
}
// Safely and automatically release the DLL.
~RaiiDll()
{
if (m_hDll)
{
::FreeLibrary(m_hDll);
m_hDll = nullptr;
}
}
// Get DLL module handle.
HMODULE Get() const
{
return m_hDll;
}
private:
HMODULE m_hDll; // DLL instance handle
//
// Ban copy (if compiler supports new C++11 =delete, use it)
//
private:
RaiiDll( RaiiDll & );
RaiiDll & operator=( RaiiDll & );
};
Then, in some code block, you can have:
{
// Load the library (throws on error).
RaiiDll scannerDll(L"WinScanner.dll");
// Get DLL function pointer
auto pCreateNewScanner = reinterpret_cast<CreateNewScannerPtr>(
GetProcAddress(scannerDll.Get(), "CreateNewScanner"));
if (! pCreateNewScanner)
{
.... error.
}
.... use the function
} // <--- DLL automatically released thanks to RaiiDll destructor!!!
Note how code is simplified thanks to automatic invocation of RaiiDll destrutor (and so of FreeLibrary), also in the error path case.

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++

calling DLL functions problem

code:
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
void calldll();
int main(int argc, char *argv[])
{
calldll();
system("PAUSE");
return EXIT_SUCCESS;
}
void calldll()
{
HINSTANCE LoadMe;
LoadMe = LoadLibrary("Trans_ATL.dll");
if(LoadMe!=0)
cout<<"loaded successfully\n";
else
cout<<"loading error\n";
/* get pointer to the functions in the dll*/
FARPROC function01 = GetProcAddress(LoadMe,"EnableLastCharTashkeel");
FARPROC function02 = GetProcAddress(LoadMe,"EnableEmphaticLAM_RAA");
FARPROC function03 = GetProcAddress(LoadMe,"SetText");
FARPROC function04 = GetProcAddress(LoadMe,"GetResult");
typedef void (__stdcall * pICFUNC01)(bool);
typedef void (__stdcall * pICFUNC02)(bool);
typedef bool (__stdcall * pICFUNC03)(string);
typedef string (__stdcall * pICFUNC04)(string);
pICFUNC01 EnableLastCharTashkeel_function;
EnableLastCharTashkeel_function = pICFUNC01(function01);
pICFUNC02 EnableEmphaticLAM_RAA_function;
EnableEmphaticLAM_RAA_function = pICFUNC02(function02);
pICFUNC03 SetText_function;
SetText_function = pICFUNC03(function03);
pICFUNC04 GetResult_function;
GetResult_function = pICFUNC04(function04);
EnableLastCharTashkeel_function(true);
EnableEmphaticLAM_RAA_function(true);
FreeLibrary(LoadMe);
}
in this code i call a dll it load successfully but when i try to use any function it compile without any errors but at the line
EnableLastCharTashkeel_function(true); (first call for a function)
it froozes and give me the following
Unhandled exception at 0x00000000 in test_trans_new.exe: 0xC0000005: Access violation reading location 0x00000000.
i guess that this becuse the function pointer point to NULL but i don't know how to fix it
i use visual c++ 2010
thanks in advance
thank you for all your replies which are realy helpfull but the problem still ocurrs but i approximately know the reason if i correct the problem is that the functions i try to access are of type COM so any idea about using this type
thanks in advance
FARPROC function01 = GetProcAddress(LoadMe,"EnableLastCharTashkeel");
That's a guaranteed NULL. Calling it does go kaboom, you didn't check if the function succeeded. The exported function is not named "EnableLastCharTashkeel". A more likely string is "?EnableLastCharTashkeel##YAX_N#Z". That's the name of the function after the C++ compiler mangled it, a trick to support overloaded functions.
You can declare the function extern "C", that suppresses name mangling and makes the function name "_EnableLastCharTashkeel". Note the leading underscore, used by the 32-bit compiler to mark that the function uses the __cdecl calling convention. To be sure, run Dumpbin.exe /exports on your DLL from the Visual Studio Command Prompt, it shows the exported names.
It's most likely 0 because the symbol you were trying to find in the DLL wasn't found, which would suggest that (a) it's either not there or (b) there might be a typo in the function name or (c) the function name might be mangled because it's being exported as a decorated name. This happens quite a lot in C++...
Unless the library exporting those four functions is under your control, use dumpbin /EXPORTS and have a look at the correct spelling of the symbols.