Any call on my application to AfxGetApp() returns NULL, can anyone help?
It is a .exe project converted from a .dll project, so there may be some project configurations that I am missing. I have copied configurations from another project created with the .exe wizard but is does not work. Also, I have a CWinApp that is global.
Check your preprocessor definitions. Remove _AFXEXT.
I had a similar problem building a dll, if I copy this code (taken from another dll) AfxGetApp() returns the correct pointer:
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
}
return nRetCode;
}
Related
I have created MyComm.dll in c++, following is the psudo code of dll.
/* CommLayerIF.h */
#include "CommLayerImpl.h"
enum class COMM_LAYER
{
COMM_LAYER1,
COMM_LAYER2
}
typedef std::vector<COMM_LAYER> CommLayers;
CommLayerIF*
CreateCommLayerIFInstance()
{
return new CommLayerIF();
}
class CommLayerIF
{
public:
/*! \brief Constructor
*/
CommLayerIF();
/*! \brief Destructor
*/
virtual
~CommLayerIF() override;
__declspec(dllexport)
int
SetLayers(CommLayers CommunicationLayers);
private:
CommLayerImpl* m_commLayerImpl;
};
Following is the implementation of CommLayerIf
/* CommLayerIF.cpp */
#include "CommLayerIF.h"
int
CommLayerIF::SetLayers(CommLayers CommunicationLayers)
{
//This function only reads vector and creates layers. It asserts after return.
int status = m_commLayerImpl.SetLayers(CommLayers);
return status;
}
Following is the application loading this DLL dynamically.
/* MyApp.cpp */
#include "CommLayerIF.h"
int main(int argc, char *argv[]) {
{
//Create comm layer instance from dll
CommLayerIF *pComm = CreateCommLayerIFInstance();
std::vector<COMM_LAYER> commLayers;
commLayers.resize(2);
commLayers[0] = COMM_LAYER::COMM_LAYER1;
commLayers[1] = COMM_LAYER::COMM_LAYER2;
int status = pComm->SetLayers(commLayers);
....
}
The SetCommLayers(CommLayers) API taking vector by value and it internally passes the vector to another function. The application links the dll dynamically and calls SetCommLayer() API, but while returning from the API it asserts during vector deallocation with following reason from debug_heap.cpp,
_ASSERTE(__acrt_first_block == header);
Note: This issue is catched in Debug mode. I have tried to build application and Dll with Multi-threaded Debug DLL (/MDd) options, But still it asserts in Debug mode.
Please let me know why its failing? Is there any solution for this issue?
I have tried multiple things but the base comes to this:
#include <stdio.h>
#include <afxwin.h>
main( int argc, const char* argv[] )
{
printf( "\nHello World\n\n" );
CDialog *dlg = new CDialog();
dlg->DoModal();
while (true) {
Sleep(1); // Sleep is a windows function
}
}
When I run this, I get the following error:
What am I missing for this dialog?
I looked up several resources, but everything results in the same error message.
Can someone tell me what am I not seeing?
Using the MFC in a console application requires some initializations.
Without this you will get asserts.
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
return 8;
}
You must also use a resource that is bound to the CDialog. You may use the appropriate constructors. Or you derive your own dialog from CDialog using the class wizard.
But it doesn't make sense to me to create an MFC console application and use dialogs... Your question may need more details, what you want to do, and why you want to do it in this way.
You may need to read some books or article before you continue this way of programming.
I am trying to port a 32-bit dll (and application) to 64-bit and I have managed to build it without errors. When trying to load it with my 64-bit application I noticed that the exported function names differ. This is how I export the functions:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) long __stdcall Connect(char * name, long size);
#ifdef __cplusplus
}
#endif
In Dependency Walker the exported functions have the following format:
32-bit: _Connect#8
64-bit: Connect
In the application using the dll I explicitly load the dll (LoadLibrary is successful) but GetProcAddress fails for 64-bit because it cannot find a function with the provided name.
In our application I keep the function names as follows:
#define ConnectName "_Connect#8"
...
GetProcAddress(Dll, ConnectName);
So I was wondering if it is possible to export the same function names for both 32-bit and 64-bit dlls or is this a bad idea? Or do I need to do the following in my applications:
#if _WIN64
#define ConnectName "Connect"
#else
#define ConnectName "_Connect#8"
#endif
I appreciate any help.
An option you have to export function names without any decoration (independently from the particular calling convention you used in x86, __stdcall, __cdecl, or other) and with the same undecorated name in both x86 and x64 builds, is to export your DLL functions using DEF files.
E.g. you could add a .DEF file like this to your project:
LIBRARY YOURDLL
EXPORTS
Connect #1
AnotherFunction #2
... etc. ...
Repro Follows
Create an empty solution in Visual Studio (I used VS2013), and inside that create an empty Win32 console project (the test client) and an empty Win32 DLL project (the test DLL).
Add this NativeDll.def .DEF file in the DLL project:
LIBRARY NATIVEDLL
EXPORTS
SayHello #1
Add this NativeDll.cpp C++ source code in the DLL project:
///////////////////////////////////////////////////////////////////////////////
//
// NativeDll.cpp -- DLL Implementation Code
//
///////////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include <atldef.h>
#include <atlstr.h>
//
// Test function exported from the DLL
//
extern "C" HRESULT WINAPI SayHello(PCWSTR name)
{
//
// Check for null input string pointer
//
if (name == nullptr)
{
return E_POINTER;
}
try
{
//
// Build a greeting message and show it in a message box
//
CString message;
message.Format(L"Hello %s from the native DLL!", name);
MessageBox(nullptr, message, L"Native DLL Test", MB_OK);
// All right
return S_OK;
}
//
// Catch exceptions and convert them to HRESULT codes
//
catch (const CAtlException& ex)
{
return static_cast<HRESULT>(ex);
}
catch (...)
{
return E_FAIL;
}
}
Add this NativeClient.cpp C++ source code in the client test project:
///////////////////////////////////////////////////////////////////////////////
//
// NativeClient.cpp -- EXE Test Client Code
//
///////////////////////////////////////////////////////////////////////////////
#include <Windows.h>
//
// Prototype of the function to be loaded from the DLL
//
typedef HRESULT (WINAPI *SayHelloFuncPtr)(PCWSTR /* name */);
//
// Simple RAII wrapper on LoadLibrary()/FreeLibrary().
//
class ScopedDll
{
public:
//
// Load the DLL
//
ScopedDll(PCWSTR dllFilename) throw()
: m_hDll(LoadLibrary(dllFilename))
{
}
//
// Unload the DLL
//
~ScopedDll() throw()
{
if (m_hDll)
{
FreeLibrary(m_hDll);
}
}
//
// Was the DLL loaded successfully?
//
explicit operator bool() const throw()
{
return (m_hDll != nullptr);
}
//
// Get the DLL handle
//
HINSTANCE Get() const throw()
{
return m_hDll;
}
//
// *** IMPLEMENTATION ***
//
private:
//
// The wrapped raw DLL handle
//
HINSTANCE m_hDll;
//
// Ban copy
//
private:
ScopedDll(const ScopedDll&) = delete;
ScopedDll& operator=(const ScopedDll&) = delete;
};
//
// Display an error message box
//
inline void ErrorMessage(PCWSTR errorMessage) throw()
{
MessageBox(nullptr, errorMessage, L"*** ERROR ***", MB_OK | MB_ICONERROR);
}
//
// Test code calling the DLL function via LoadLibrary()/GetProcAddress()
//
int main()
{
//
// Return codes
//
static const int kExitOk = 0;
static const int kExitError = 1;
//
// Load the DLL with LoadLibrary().
//
// NOTE: FreeLibrary() automatically called thanks to RAII!
//
ScopedDll dll(L"NativeDll.dll");
if (!dll)
{
ErrorMessage(L"Can't load the DLL.");
return kExitError;
}
//
// Use GetProcAddress() to access the DLL test function.
// Note the *undecorated* "SayHello" function name!!
//
SayHelloFuncPtr pSayHello
= reinterpret_cast<SayHelloFuncPtr>(GetProcAddress(dll.Get(),
"SayHello"));
if (pSayHello == nullptr)
{
ErrorMessage(L"GetProcAddress() failed.");
return kExitError;
}
//
// Call the DLL test function
//
HRESULT hr = pSayHello(L"Connie");
if (FAILED(hr))
{
ErrorMessage(L"DLL function call returned failure HRESULT.");
return kExitError;
}
//
// All right
//
return kExitOk;
}
Build the whole solution (both the .EXE and the .DLL) and run the native .EXE client.
This is what I get on my computer:
It works without modifications and with the undecorated function name (just SayHello) on both x86 and x64 builds.
__stdcall is not supported (and is ignored) on x64. Quoting MSDN:
On ARM and x64 processors, __stdcall is accepted and ignored by the compiler; on ARM and x64 architectures, by convention, arguments are passed in registers when possible, and subsequent arguments are passed on the stack.
The calling convention on x64 is pretty much __fastcall.
Since the calling conventions and name decoration rules on x86 and x64 differ, you have to abstract this somehow. So your idea with #if _WIN64 goes in the right direction.
You can examine x86 calling conventions and your needs and perhaps devise a macro which could automate the name selection process.
As you can tell, in 64-bit Windows names are not decorated.
In 32-bit __cdecl and __stdcall symbols, the symbol name is prepended by an underscore. The trailing '#8' in the exported name for the 32-bit version of your example function is the number of bytes in the parameter list. It is there because you specified __stdcall. If you use the __cdecl calling convention (the default for C/C++ code), you won't get that. If you use __cdecl, it makes it much easier to wrap GetProcAddress() with something like:
#if _WIN64
#define DecorateSymbolName(s) s
#else
#define DecorateSymbolName(s) "_" ## s
#endif
then just call with
pfnConnect = GetProcAddress(hDLL, DecorateSymbolName("Connect"));
pfnOtherFunc = GetProcAddress(hDLL, DecorateSymbolName("OtherFunc"));
or something similar (error checking omitted in example).
To do this, remember to declare your exported functions as:
__declspec(dllexport) long __cdecl Connect(char * name, long size);
__declspec(dllexport) long __cdecl OtherFunc(int someValue);
In addition to being easier to maintain, if during development the signature of an exported function changes, you don't have to screw around with your #define wrappers.
Downside: if during development the number of bytes in a given function's parameter list changes, it will not be caught by the application importing the function because the changing the signature will not change the name. Personally, I don't think this is an issue because the 64-bit build would blow up under the same circumstances anyway as the names are not decorated. You just have to make sure your application is using the right version of the DLL.
If the user of the DLL is using C++, you can wrap things in a better way using C++ capabilities (wrap the entire explicitly-loaded library in a wrapper class, e.g.):
class MyDLLWrapper {
public:
MyDLLWrapper(const std::string& moduleName); // load library here
~MyDLLWrapper(); // free library here
FARPROC WINAPI getProcAddress(const std::string& symbolName) const {
return ::GetProcAddress(m_hModule, decorateSymbolName(symbolName));
}
// etc., etc.
private:
HMODULE m_hModule;
// etc.
// ...
};
There's actually a lot more you can do with a wrapper class like this, it's just an example.
On edit: since OP mentioned using PInvoke in the comments - if anyone decides to do this, do not forget to add CallingConvention = CallingConvention.Cdecl in the [DllImport] declaration when using PInvoke. __cdecl might be the default for unmanaged C/C++, but is not the default for managed code.
For Win32 build:
If you use __stdcall, you will get something like this (dumped with dumpbin /exports):
__declspec(dllexport) int __stdcall
->
ordinal hint RVA name
1 0 00001240 _F1#0 = _F1#0
2 1 0000124D _F2#0 = _F2#0
And you have to use GetProcAddress("_F1#0") to locate the function pointer.
If you use __cdecl, you will get something like this:
__declspec(dllexport) int __cdecl
->
ordinal hint RVA name
1 0 00001240 F1 = _F1
2 1 0000124D F2 = _F2
And you can use GetProcAddress("F1") to locate the function pointer.
BTW, if you add a XXX.def file to your Visual Studio project. One more link option will be silently added to your linker command line /DEF:"XXX.def" in the All Options window. And if you change your .def file name later for whatever reason, this link option doesn't change accordingly. You need to manually change the def file name in the project properties window.
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.
I have custom binary resources (animated cursors) that would like to store as resources in a static lib in Visual Studio C++. It turns out that custom binary resources will not get loaded by ::LoadCursor() or found by ::FindResource() if it is a custom resource and in a static library.
This question
gives some work around.
Following its advice, if I add the *.res file to an exe as a "Configuration Property->Linker->Additional Dependency" then the static library will be able to find the resource.
BUT if the static library is part of a dll and I link it in as an Additional Dependency it is not found again!
How can I link the resources in a dll?
Or just make the binary be found in the static lib? The methods in the question are pretty cumbersome.
In Add Resource dialog click Import, select "All Files (.)" so that it allows you to import file of any type, and then just select the file you want there. When Custom Resource Type dialog pops up, type RCDATA into "Resource type" field.
If you open .rc file, you will see something like this:
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_RCDATA1 RCDATA "myfile.whatever"
and it will generate resource.h with following line:
#define IDR_RCDATA1 101
In code you access it like this:
#include "resource.h"
#include <windows.h>
int main(int argc, char* argv[])
{
HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA);
HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
void* pMyBinaryData = ::LockResource(myResourceData);
return 0;
}
where pMyBinaryData is pointer to first byte of this executable. For more information visit
Resource Functions
Here's an example how you would save binary resource like this on disk:
#include "resource.h"
#include <windows.h>
#include <fstream>
int main(int argc, char* argv[])
{
HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA);
unsigned int myResourceSize = ::SizeofResource(NULL, myResource);
HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
void* pMyBinaryData = ::LockResource(myResourceData);
std::ofstream f("C:\\x.bin", std::ios::out | std::ios::binary);
f.write((char*)pMyBinaryData, myResourceSize);
f.close();
return 0;
}
When you build project with resource like that, this resource will become part of your program (dll).
The Problem of #LihO answer is:
The first parameter of FindResource is the ModuleID of the Module containing the resources. If this is set to NULL the function will search in created process (.exe), not the DLL.
But how to get the HMODULE insinde a static LIB?
add a function / parameter, which will get the HMODULE from the DLL. The HMODULE / HINSTANCE (is the same) can be retrieved in DLLMain.
Try this GetCurrentModule
Edit:
See also: Add lib resource to a library
In case you use dll using MFC (and CWinApp), you can obtain the HMODULE from CWinApp.
extern MyDllApp theApp;
HMODULE module = (HMODULE)theApp.m_hInstance;
HRSRC myResource = ::FindResource(module,
MAKEINTRESOURCE(IDR_FILE_RESOURCE), _T("GROUP_NAME"));
If you supply NULL in FindResource, application won't find your resource.