Loader lock (regsvr32 R6033 error) with managed C++ dll - c++

I have a C++ dll which implements several COM interfaces, that I'm trying to migrate to managed C++. I set the /clr compiler flag and changed the Runtime Library property from /MT to /MD to avoid the conflict between these two flags, but that's all I've changed. When it attempts to register the dll during the build process, I get the following error:
R6033 - Attempt to use MSIL code from this assembly during native code initialization
This indicates a bug in your application. It is most likely the result of calling an MSIL-compiled (/clr) function from a native constructor or from DllMain.
I read about Loader Lock and can't figure it out - I have not added a single call to any managed code. Here's the entire body of the DllMain procedure:
[Edit - per comment below, I added #pragma unmanaged to the top of the cpp file with no improvement. The Module init is all code contained in the ATL libraries from what I can tell.]
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
lpReserved;
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance, &MYGUID);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE; // ok
}

You need to add the /clr compiler flag only to the files that use managed code and not for the whole project.
This is what the Visual Studio "Wizard" does, here is how I've tested:
Create a Visual C++ ATL Project
Added a ATL Simple Object, in order to have a COM interface (Project->Add Class)
Added a CLR Component Class. The Wizard prompted me with "You are adding a CLR component to a native project. Your project will be converted to have Common Language Runtime support."
Compile project, compiles fine and registers fine.
Checked the project settings -> "No Common Language Runtime support"
Checked the clrcomponennt.cpp settings -> "Common Language Runtime Support (/clr)"
Opened the dll in OleView -> COM interface was present
Opened the dll in Red Gate's .NET Reflector -> clrcomponent was present

Using /clr flag has made your methods managed (ie. they are being compiled down to MSIL), but you're calling them for DllMain which -isn't- managed. Unfortunately, that's about as far as my limited knowledge can take it.

Related

How can I debug a C++ dynamic library?

How can I debug the dynamic library conveniently and quickly in Visual Studio 2022?
If Xenos injection is used, nothing is output (random process).
If it passes through the attached process, it does not enter any breakpoint (random process).
#include "pch.h"
#include <iostream>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
std::system("ls>1.txt");
case DLL_PROCESS_ATTACH:
OutputDebugString(TEXT("INterdll"));
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
In Visual Studio 2022 you can debug your own library by attaching to the application which uses your library. When I usually develop C++ libraries, I create a separate project which called <MyLibrary>Tests and connect gtest library.
This way guarantees that your library will be under testing and when you'll run your tests, you could attach to this process.
To attach your codebase to the application, you have to use menu option Debug → Attach to Process...:
When you press it, you'll be able to find your application which is using your library currently.
And, as I understand on my last work place, the best way to debug your library is make your small GUI application with some buttons for testing. It's pretty enough to make a simple Python app to check it.
From Specify symbol (.pdb) and source files in the Visual Studio debugger (C#, C++, Visual Basic, F#), the quickest way to fix this is via the Modules Window in the Debugger:
Put a breakpoint after your call.LoadLibrary
Go to Debug->Windows->Modules in the menu bar to bring up the Modules window.
Search for your dll file in the list. In the Symbol Status column it should read "Cannot find or open the PDB file".
Right click the dll and choose Load Symbols from the context menu.
Point it to the correct pdb file.
The Symbol Status should now change to "Symbols Loaded".
You should now be able to step into functions from the dll and add breakpoints.

VC++ Dll Not Working On Windows XP Sp3 When Using C++ Builder

I have created VC++ Dll in Visual Studio 2013.
extern "C" int __declspec(dllexport) __cdecl ConvertImageToText(char* dataPath, char* imageFilePath, char* captchaCode)
{
// to do
return 0;
}
I'm using in Borland C++ Builder 6 like that.
HMODULE dllHandle = LoadLibrary("Captcha.dll");
int (__cdecl *ConvertImageToText)(char*,char*,char*);
ConvertImageToText =(int (__cdecl *)(char*,char*,char*))GetProcAddress(dllHandle, "ConvertImageToText");
if (ConvertImageToText != NULL )
{
ConvertImageToText("","","");
}else
{
ShowMessage("ConvertImageToText pointer not found !");
}
it's working well in win7/8/8.1.there isn't any problem.
But can't find pointer of ConvertImageToText on windows xp sp3.
I have changed VC++ Dll Project "Platform Toolset" as "Visual Studio 2013 - Windows XP (v120_xp)".nothing not changed.
I have checked Visual C++ Redistributable packages.All installed
Any sugguestions ?
You need to implement proper error checking as described by the documentation.
Test the return value of LoadLibrary. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
E. Test the return value of GetProcAddress. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
Likely LoadLibrary is failing because your DLL is linked to a runtime that is not installed on the target machine, or because your DLL is linked to Win32 API functions that do not exist on XP.
If you cannot work it out from here you can use Dependency Walker for extra debugging. Use it in profile mode to debug the loader's attempt to load the DLL. That will reveal enough information to diagnose the problem.
I have installed that redist release. it worked.

How to migrate a program with Common Controls from Visual C++ 6.0 to Visual C++ 2010 (on 64-bit machine)

I am attempting to migrate a Visual C++ 6.0 program (originally written on a Windows NT machine) to Visual C++ 2010 for use on my 64-bit Windows 7 PC. The program compiles fine but there is a runtime assertion failure which yeilds the following output in the debugger:
CoCreateInstance of OLE control {F9043C85-F6F2-101A-A3C9-08002B2F49FB}
failed.
Result code: 0x80040154
Is the control is properly registered?
Warning: Resource items and Win32 Z-order lists are out of sync. Tab
order may be not defined well.
Warning: CreateDlgControls failed during dialog init.
The failed assertion is on line 925 of occcont.cpp:
ASSERT(IsWindow(pTemp->m_hWnd));
I understand from http://dynamicsuser.net/forums/p/25968/140697.aspx that the Microsoft Common Dialog Control v6.0 might not be registered. I registered it with Regsrv32.exe and restarted windows but the error persists.
My goal is to tell whether this old program can work with new tools--not to actually rewrite the old program (though that will come later). Is it possible to make the old program run on my newer machine?
EDIT: Addition of the code which causes the assertion failure
BOOL CCameraSimulationApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
if (!InitCommonControlsEx(&InitCtrlEx))
{
printf("Common Controls failed to initialize");//debug
}
CCameraSimulationDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
...
0x80040154 is REGDB_E_CLASSNOTREG. That means that the class has not been registered.
{F9043C85-F6F2-101A-A3C9-08002B2F49FB} is the Commom Dialog Control.
So, it seems that that control is not registered. You attempted to register it but I'd guess that you registered the 64 bit version. You are likely compiling a 32 bit program and so need to register the 32 bit version.
regsvr32 C:\Windows\SysWOW64\ComDlg32.ocx
Make sure you do this whilst elevated. That said, I would expect the control to be registered out of the box.
Finally, it's 2015 now and you should not be using this control anymore. Try to wean yourself onto something more modern.
I'd also comment that there's no need for you to re-compile the program. To start with I'd concentrate on getting your existing executable to work on the new machine.

Unable to import MFCreateDXSurfaceBuffer function

I am working on some video editing software and need to use some Direct3D components to improve performance. Specifically, I need to use the MFCreateDXSurfaceBuffer function to create samples from a direct3d surface. After adding code to use this function, I get the following message when trying to run the compiled executable:
The procdedure entry point MFCreateDXSurfaceBuffer could not be located in the dynamic link library MFPlat.dll
Output window: The program '[0x1C04] ClassLibrary1.exe: Native' has exited with code -1073741511 (0xc0000139) 'Entry Point Not Found'.
I created a minimalistic project that reproduces the problem:
#include < mfapi.h >
#include < d3d9.h >
#include < evr.h >
static void
Fail
(
)
{
IDirect3DSurface9* theSurface = nullptr;
IMFMediaBuffer* theBuffer = nullptr;
MFCreateDXSurfaceBuffer(__uuidof(IDirect3DSurface9), theSurface, FALSE, &theBuffer);
}
int main()
{
Fail();
}
I added "evr.lib;mfplat.lib;D3d9.lib" to Properties->Linker->Input Additional dependencies
I am using:
Windows 7 64 bit
MS Visual Studio 2012
C++
What I've tried:
Google - no mention of a similar problem
Ran the code on a co worker's machine. Same issue occurs.
Call other functions from evr.dll. Some work, some have the same problem
Dependency Walker: mini project EXE Depends on MFPLAT.DLL, MSVCR110D.DLL and KERNEL32.DLL.
Error message:
"At least one module has an unresolved import due to a missing export function in an implicitly dependent module."
Obviously, the function that did not import was MFCreateDXSurfaceBuffer.
You may have noticed that MFCreateDXSurfaceBuffer is defined EVR.dll, which is conspicuously absent from my dependency list.
Why is the function failing to import and how do I fix it?
The procdedure entry point MFCreateDXSurfaceBuffer could not be located in the dynamic link library MFPlat.dll
MFCreateDXSurfaceBuffer function is exported off evr.dll, not mfplat.dll - you already discovered this. I suppose you might be using some wrong/corrupt Windows SDK version. At least with Windows SDK 7.0 the code builds and starts fine. Besides the code snippet quoted above you only need to add evr.lib as additional linker input.
I'm also facing this issue.
For the record, I'm writing the solution I found here :
HMODULE evrModule = LoadLibraryA("evr.dll");
/* MFCreateDXSurfaceBuffer prototype */
typedef HRESULT(STDAPICALLTYPE *MFCDXSB)(_In_ REFIID iid, _In_ IUnknown *unkSurface, _In_ BOOL bottomUpWhenLinera, _Out_ IMFMediaBuffer **mediaBuffer);
MFCDXSB pMFCreateDXSurfaceBuffer = (MFCDXSB)GetProcAddress(evrModule, "MFCreateDXSurfaceBuffer");
Do not forget to check for errors and to call FreeLibrary(evrModule) at the end
I tried several things and they all failed. I know this is a bit hardcore but at least it works and I only do this for this method so I guess it's ok.
After coming across this problem, I searched the library files in the Windows SDK directory and found a .lib file that exports the MFCreateDXSurfaceBuffer function. The file is called evr_vista.lib.
I have no clue why EVR functions have been split into the evr.lib and evr_vista.lib.
Adding "evr_vista.lib" in addition to "evr.lib" to the list of libraries to link with should resolve any linking errors.
Under Visual Studio:
Project Properties > Configuration Properties > Linker > Input > Additional Dependencies

Calling functions in a DLL from C++

I have a solution in VS 2008 with 2 projects in it. One is a DLL written in C++ and the other is a simple C++ console application created from a blank project. I would like know how to call the functions in the DLL from the application.
Assume I am starting with a blank C++ project and that I want to call a function called int IsolatedFunction(int someParam)
How do I call it?
There are many ways to do this but I think one of the easiest options is to link the application to the DLL at link time and then use a definition file to define the symbols to be exported from the DLL.
CAVEAT: The definition file approach works bests for undecorated symbol names. If you want to export decorated symbols then it is probably better to NOT USE the definition file approach.
Here is an simple example on how this is done.
Step 1: Define the function in the export.h file.
int WINAPI IsolatedFunction(const char *title, const char *test);
Step 2: Define the function in the export.cpp file.
#include <windows.h>
int WINAPI IsolatedFunction(const char *title, const char *test)
{
MessageBox(0, title, test, MB_OK);
return 1;
}
Step 3: Define the function as an export in the export.def defintion file.
EXPORTS IsolatedFunction #1
Step 4: Create a DLL project and add the export.cpp and export.def files to this project. Building this project will create an export.dll and an export.lib file.
The following two steps link to the DLL at link time. If you don't want to define the entry points at link time, ignore the next two steps and use the LoadLibrary and GetProcAddress to load the function entry point at runtime.
Step 5: Create a Test application project to use the dll by adding the export.lib file to the project. Copy the export.dll file to ths same location as the Test console executable.
Step 6: Call the IsolatedFunction function from within the Test application as shown below.
#include "stdafx.h"
// get the function prototype of the imported function
#include "../export/export.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// call the imported function found in the dll
int result = IsolatedFunction("hello", "world");
return 0;
}
Can also export functions from dll and import from the exe, it is more tricky at first but in the end is much easier than calling LoadLibrary/GetProcAddress. See MSDN.
When creating the project with the VS wizard there's a check box in the dll that let you export functions.
Then, in the exe application you only have to #include a header from the dll with the proper definitions, and add the dll project as a dependency to the exe application.
Check this other question if you want to investigate this point further Exporting functions from a DLL with dllexport.
The following are the 5 steps required:
declare the function pointer
Load the library
Get the procedure address
assign it to function pointer
call the function using function pointer
You can find the step by step VC++ IDE screen shot at http://www.softwareandfinance.com/Visual_CPP/DLLDynamicBinding.html
Here is the code snippet:
int main()
{
/***
__declspec(dllimport) bool GetWelcomeMessage(char *buf, int len); // used for static binding
***/
typedef bool (*GW)(char *buf, int len);
HMODULE hModule = LoadLibrary(TEXT("TestServer.DLL"));
GW GetWelcomeMessage = (GW) GetProcAddress(hModule, "GetWelcomeMessage");
char buf[128];
if(GetWelcomeMessage(buf, 128) == true)
std::cout << buf;
return 0;
}
You can either go the LoadLibrary/GetProcAddress route (as Harper mentioned in his answer, here's link to the run-time dynamic linking MSDN sample again) or you can link your console application to the .lib produced from the DLL project and include the hea.h file with the declaration of your function (as described in the load-time dynamic linking MSDN sample)
In both cases, you need to make sure your DLL exports the function you want to call properly. The easiest way to do it is by using __declspec(dllexport) on the function declaration (as shown in the creating a simple dynamic-link library MSDN sample), though you can do it also through the corresponding .def file in your DLL project.
For more information on the topic of DLLs, you should browse through the MSDN About Dynamic-Link Libraries topic.
Might be useful: https://www.codeproject.com/Articles/6299/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-4
For the example above with "GetWelcomeMessage" you might need to specify "__stdcall" in the typedef field before the function name if getting error after calling imported function.
Presuming you're talking about dynamic runtime loading of DLLs, you're looking for LoadLibrary and GetProAddress. There's an example on MSDN.
When the DLL was created an import lib is usually automatically created and you should use that linked in to your program along with header files to call it but if not then you can manually call windows functions like LoadLibrary and GetProcAddress to get it working.