ShowMessage not showing in Delphi DLL called from C++ - c++

I want to call this delphi code via a DLL from C++
procedure MyMessage; stdcall;
begin
ShowMessage(DLLName + ' more text');
end;
Using some delphi test code I see no problem , but from C++ no message box is shown.
i did the following C++ coding
// function prototype
typedef void(__stdcall*VoidCall)();
// prototype for info function inside DLL
extern "C" __declspec(dllimport) void __stdcall MyMessage();
MyMessage = (VoidCall)::GetProcAddress(load, "MyMessage");
MyMessage;
As I want to use as a next steps existing delphi forms with a wrapper DLL from C++ , I guess the solution of this problem will also enable me for the next task ....

The presented C++ code does not compile. It mixes binding of a dll via an import library with dynamic loading of a dll via LoadLibrary / GetProcAddress.
To load a DLL created with Delphi, it is easiest to use dynamic loading of the dll. Do this as follows:
// function prototype
typedef void(__stdcall*VoidCall)();
[...]
// Load the library
HMODULE lib = LoadLibrary("Project1.dll");
if (lib != 0)
{
__try
{
// Get the address to the exported function in the DLL
// and store it in the variable myMessageFunction
VoidCall myMessageFunction = (VoidCall) GetProcAddress(lib, "MyMessage");
// Call the function. Note you need the parenthesis even
// when there are no parameters to pass
myMessageFunction();
}
__finally
{
// Unload the library again. Note that you cannot use
// functions from the library after that. So only unload
// the dll once you don't need it anymore.
FreeLibrary(lib);
}
}
else // TODO: Error handling, dll cannot be loaded
If you want to use load time linking, you can create a *.lib file to be used with C++ for a DLL created with Delphi. Use the solution from this question.

Related

dynamically loading a dll that uses the applications methods

I want to change and test my dll function build for an application without constantly closing and starting the application itself, which takes a lot of time. Hence I build a calling dll for the application to load, and another testing dll (which i load dynamically), where I can change my testing function in real time, without closing the application.
The application loads automatically the calling dll, wherein I can dynamically load my testing dll and call an empty function succesfully :
calling dll:
typedef void(__stdcall *test_func)(void);
HINSTANCE hdl = LoadLibraryA("C:\\testingfunction.dll");
test_func func = (test_func) GetProcAddress(hdl, "?testingfunc##YAXXZ");
func();
In the testing function dll I have:
testingfunction.h
#define DLL_API _declspec(dllexport)
DLL_API void __stdcall testingfunc();
testingfunction.cpp
DLL_API void __stdcall testingfunc()
{
double a = 3 * 4.2;
//PlugIn::gResultOut << " ...I am alive... " << std::endl;
return;
}
So if the printing line is commented out, the function works in the application, meaning it does not crash. But when I uncomment the printing line, the application crashes. It seems I cannot use the methods and functions of the application itself.
How would I fix this? Do I need to use __declspec(dllimport), and if so, how?
thanks!

C++ XE 5 Application and C++ Builder 5 dll compatibility

I have BCB5 dll with method:
extern "C" void __declspec(dllexport) __stdcall SM(TDataSource *DS) {
TForm *form = new TForm(Application);
form->Width = 300;
form->Height = 300;
form->Name = "frm";
TDBGrid *grd = new TDBGrid(form);
grd->Parent = form;
grd->Name = "grd";
grd->Align = alClient;
grd->DataSource = DS;
form->ShowModal();
}
When I call this method from C++ builder 5 application, it's working fine.
try {
typedef void __declspec(dllexport) __stdcall SM(TDataSource *DS);
SM *Upload;
HINSTANCE hDll = LoadLibrary("main.dll");
Upload = (SM*) GetProcAddress(hDll,"SM");
Upload(DataSource1);
FreeLibrary(hDll);
}
catch (Exception *ex) {
ShowMessage(ex->Message);
}
But, if I'm trying to call this method from C++ XE 5 application, I get Access Violation.
Is there a way to solve the problem of data transmission from XE 5 application to BCB 5 dll without recompile dll in XE5?
It is not safe to pass/use RTL/VCL objects over the DLL boundary like you are doing, unless both EXE and DLL are compiled with Runtime Packages enabled so that they share a common instance of the same RTL and VCL frameworks (but then you have to deploy the RTL/VCL BPL binaries with your app).
Your DLL doesn't work in XE5 because the DLL is expecting the BCB5 version of the TDataSource component, not the XE5 version. No, they are not compatible, as they have different memory layouts and dependancies.
So your choices are to either:
recompile the DLL in XE5, and live with the risk that passing TDataSource over the DLL boundary is not safe in general, unless you enable Runtime Packages.
re-write the DLL to be a Runtime Package (BPL) instead. Then passing TDataSource between EXE and DLL is safe. However, Runtime Packages are version-specific, so you will need to compile separate BPLs if you need to continue using the code in both BCB5 and XE5.
re-write the DLL to not pass a TDataSource over the DLL boundary to begin with. Figure out another interop-safe way to exchange data between EXE and DLL.

MFC app and shared libs

I have a application which seems has written in MFC (process hacker and DependencyWalker show link to MFC90).
Also, There is a library(FTD2XX) in the installation path. But the DependencyWalker won't show the MFC90 link for the lib and show:
SetupAPI.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
In what framework the lib is built?
I don't have experience in MFC. I don't have information in its compiler and if VC++ libs can be used to link with MFC apps.
If you want to log calls going to a dll, the best way is to write a proxy dll (a dll redirection). But for that you must know the signature (syntax) of the function which you are going to override, i.e. exact number of parameters, their types and return type etc. If I can assume that you somehow can find out signature of all the functions in ftd2xx.dll, then it is merely simple to get it done.
Get dll functions and Ordinal numbers:
For this just use dumpbin.exe comes with Visual Studio (use it by running Visual Studio command prompt)
dumpbin.exe /exports {yourpath}\ftd2xx.dll > ftd2xx.txt
Now your ftd2xx.txt has all the function names and ordinal numbers of the ftd2xx.dll. You can even use your dependency walker to export and get this list.
Create you own dll named ftd2xx.dll:
Open Visual Studio, choose VC++ >> Win32 >> Win32 Project >> Dll (with Export symbols option) and finally use #pragma directive to declare all your exported original dll functions within your dll code like below,
//#pragma comment (linker, "/export:<function>=<origdll_name>.<function>,#<ordinal_number>")
#pragma comment (linker, "/export:FT_Open=ftd2xx_.FT_Open,#1")
#pragma comment (linker, "/export:FT_Close=ftd2xx_.FT_Close,#2")
// :
// :
// :
// delcare all your exported functions here with ordinal number
// :
// :
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
}
Now, you need to write your own function which can pretend as an original function of ftd2xx.dll which will get called when the application calls a original function of ftd2xx.dll. The below code is just to explain how it works. As I said earlier you need to know the exact signature of the dll functions which you want to override (redirect). And also keep in mind that you need to call the original function after whatever you wanted to do, otherwise you may endup having unexpected behaviour with your application.
Assuming FT_Close() function takes no parameter and returns void, I am putting this just for example in which I override FT_Close() function of ftd2xx.dll with a proxy NewFT_Close() function. Note that, if you override a function, then remove it from #pragma directive and add it in a .def file (add a new ftd2xx.def file to your project and declare your new functions like below).
DEF file example
LIBRARY ftd2xx.dll
EXPORTS
FT_Close = NewFT_Close #2
Dll code example
HINSTANCE hInstance = NULL; // handle to ftd2xx.dll
FARPROC fpFTClose = {NULL}; // function pointer to hold original function address
extern "C" void __stdcall NewFT_Close()
{
// This is our proxy function for FT_Close()
// Do whatever you want to do here and the
// finally call the original FT_Close() using
// the function pointer we got from GetProcAddress()
typedef void (__stdcall *PFTCLOSE)();
PFTCLOSE pFc = (PFTCLOSE)fpFTClose;
if(pFc) pFc();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// Load the original dll in to the memory and get the handle
hInstance = LoadLibraryA("ftd2xx_.dll");
if(!hInstance) return FALSE;
// Get the address of the function to be overriden
fpFTClose = GetProcAddress(hInstance,"FT_Close");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
// Our dll is getting unloaded from the application, unload original as well
FreeLibrary(hInstance);
break;
}
return TRUE;
}
Note that the original dll is referred as ftd2xx_.dll in LoadLibraryA() call. So, rename the original dll to ftd2xx_.dll or name it whatever you want. Build your proxy dll code and take your proxy dll (ftd2xx.dll) to the path where the original ftd2xx.dll present. Now, your application will call ftd2xx.dll (proxy) as usual, but ftd2xx.dll will call the original dll ftd2xx_.dll internally.
Update #1:
I kept mentioning that you need to know the signature of the functions your are trying to override, and by luck I just found the ftd2xx.h file in the linux version of the driver.
Linux version of ftd2xx
Download the libftd2xx-i386-1.3.6.tgz file from above link and extract it to a folder (I used 7zip), further extract the .tar file to get the release folder and you'll find ftd2xx.h file within the "release" folder. There you go, now you got complete function signatures of the dll and you know how to write a proxy dll. Good Luck.

How to load the DLL from the main project c++

I have created a project that uses 2 DLL's to play against each other (a DLL is a player). The game is that the first player picks a number and the second player picks another number, and then the PlayRound function compares the two numbers. My problem that am not sure how to load the DLL (run/load time). I created my first DLL (simple.dll) which has a Pick function that always returns "int 2" for simplicity:
#include "stdafx.h"
#define ASEXPORT
#include <iostream>
#include "player.h"
using namespace std;
int Pick(int Round, int MyMoves[], int OpponentMoves[])
{
return 2;
}
This project have a header (player.h) with the following code:
#ifndef ASEXPORT
#define DLLIMPORTOREXPORT dllimport
#else
#define DLLIMPORTOREXPORT dllexport
#endif
_declspec(DLLIMPORTOREXPORT) int Pick(int Round, int MyMoves[], int OpponentMoves[]);
Not sure where to include this code do i include it in the main or in a function:
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
//hinstLib = LoadLibrary(TEXT(player2Name));
hinstLib = LoadLibrary();
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "simple.DLL");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// Report any failures
if (! fRunTimeLinkSuccess)
printf("Unable to load DLL or link to functions\n");
if (! fFreeResult)
printf("Unable to unload DLL\n");
//
I hope I made it easy to understand
You can see this in my ModuleService implementation in the IndieZen core library. I treat .dll and .so as a "module". In my plugin system I have a standard that every module implements one and only one exported function, which is getModule() in my example, Pick() in your use case.
My example returns in implementation of I_Module interface. In my example, modules are collections of plugins, so the only thing you can do is get an implementation of an I_Plugin, which in turn can be used to gain access to class factories, and then these class factories construct objects (extensions) which implement pre-defined interfaces (extension points).
I know that's all overkill for your example, but the code is quite easy to follow; feel free to copy/paste the subsets you can use.
One key thing is to NOT use _declspec(DLLIMPORTOREXPORT) on the Pick function; you should only be exporting the function and not importing it. You should also not be linking these DLL's to your main application, nor should you include the DLL's header file into your main application. This will give you the flexibility of being able to import two separate DLL's that expose the same function (Pick in your case) without having linking errors. It will also give you the advantage of not knowing the names of the DLL's until runtime (where possibly you may want some configuration or GUI to let the user pick which players).
My implementation, with the reference counting, class factory, etc would give you an added advantage in that you could have two players implemented within the same DLL which could play against each other.

How to load a VC++ CLR library in MFC application?

HI I have a application developed in VC++6.0 ,now I want use some new features from .NET and developed a library, to develop this library I have to use the CLR-VC++ now I packaged this in a DLL.Now I need to call the routine of this DLL in my MFC application.
I tried to write a small MFC application to load this DLL, All the time the LoadLibrary() call is failing #err =126, module not found.I check the the dll with dependency walker everthig is fine there. Please Help me in this regard.
If possible provide me a sample code or link.
Thanks in advance
-Sachin
Use ClrCreateManagedInstance to create a COM-Callable-Wrapper for the object you want to call. Then use it like any other COM type.
you have to go to property page -> Common properties ->Add New reference and include you
CLR Address there .
I have a native C++ application which uses a managed C++ assembly and loads it with LoadLibrary() without problems. I had to do two things, however, before LoadLibrary() worked:
Make sure that the current directory is the one where the managed assembly resides (use chdir() to change directory)
In the managed assembly, the first function invoked by native code only defines the handler for AppDomain::CurrentDomain->AssemblyResolve event which explicitly loads assemblies from the folder of the managed application. It then invokes another managed function to do the rest of the initialization.
The reason for the last point is that CLR attempts to load an assembly dependency only if a function uses it. So I had to ensure that types in non-system assemblies are not referenced before the AssemblyResolve handler has been defined.
ref class AssemblyResolver
{
public:
/// The path where the assemblies are searched
property String^ Path
{
String^ get()
{ return path_; }
}
explicit AssemblyResolver(String^ path)
: path_(path)
{ /* Void */ }
Assembly^ ResolveHandler(Object^ sender, ResolveEventArgs^ args)
{
// The name passed here contains other information as well
String^ dll_name = args->Name->Substring(0, args->Name->IndexOf(','));
String^ path = System::IO::Path::Combine(path_, dll_name+".dll");
if ( File::Exists(path) )
return Assembly::LoadFile(path);
return nullptr;
}
private:
String^ path_;
};
extern "C" __declspec(dllexport) void Initialize()
{
String^ path = "The path where the managed code resides";
AssemblyResolver^ resolver = gcnew AssemblyResolver(path);
AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler(
resolver,
&AssemblyResolver::ResolveHandler
);
FunctionWhichUsesOtherManagedTypes();
}