App Crash for C++/CLI DLL and Exe of x64 bit - c++

Just to showcase problem I have written a simple DLL x64 of "Hello world" changed its property to CLR and Calling its Function from an Exe which is also x64 and property Changed to CLR.
But My exe prints the Output "Hello World" and crashes every time and gives FAULT Module Name KERNELBASE.dll.
When I change Property of both to NO CLR it works perfectly fine. This happens only for x64 application not observed in x86 program.
I am using Visual Studio 2017 on Windows Server 2012.
It will be very helpful if someone can guide me to correct direction.
Details of App Crash
Problem Event Name: APPCRASH
Application Name: consuming_using_clr.exe
Application Version: 0.0.0.0
Application Timestamp: 5b42fff3
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.3.9600.17055
Fault Module Timestamp: 532954fb
Exception Code: c0020001
Exception Offset: 0000000000005bf8
OS Version: 6.3.9600.2.0.0.16.7
Locale ID: 1033
Additional Information 1: 8e72
Additional Information 2: 8e72455f15a8480830570fcb3c4abf60
Additional Information 3: f8d5
Additional Information 4: f8d519c5149c6c561af747d4db7e910a
DLL dot.h file
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the DLLWINDOWSDESKTOPWIZARD_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// DLLWINDOWSDESKTOPWIZARD_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DLLWINDOWSDESKTOPWIZARD_EXPORTS
#define DLLWINDOWSDESKTOPWIZARD_API __declspec(dllexport)
#else
#define DLLWINDOWSDESKTOPWIZARD_API __declspec(dllimport)
#endif
#using<System.dll>
#include<iostream>
using namespace System;
using namespace std;
// This class is exported from the Dll_windows_desktop_wizard.dll
class DLLWINDOWSDESKTOPWIZARD_API CDllwindowsdesktopwizard
{
public:
CDllwindowsdesktopwizard(void);
~CDllwindowsdesktopwizard(void);
void helloworld();
};
*DLL DOT CPP File *
// Dll_windows_desktop_wizard.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "Dll_windows_desktop_wizard.h"
// This is the constructor of a class that has been exported.
// see Dll_windows_desktop_wizard.h for the class definition
CDllwindowsdesktopwizard::CDllwindowsdesktopwizard(void)
{
}
CDllwindowsdesktopwizard::~CDllwindowsdesktopwizard(void)
{
}
void CDllwindowsdesktopwizard::helloworld()
{
Console::WriteLine("Hello World");
}
EXE Calling DLL Function
#include<iostream>
#include "Dll_windows_desktop_wizard.h"
using namespace System;
int main()
{
CDllwindowsdesktopwizard lv_obj;
lv_obj.helloworld();
return 0;
}
dllMain.cpp
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Finally I got it.Came across this link https://msdn.microsoft.com/en-us/library/ccthbfk8.aspx as i was trying to remove the warning from my exe warning was
"warning:Calling managed 'DllMain': Managed code may not be run under loader lock,including the DLL entrypoint and calls reached from the DLL entrypoint"

Related

Set custom EntryPoint for a simple application

I have this simple hello world c++ application:
#include <windows.h>
#include <iostream>
using namespace std;
void test()
{
cout << "Hello world" << endl;
}
I want to use test as my custom entry point. So far I tried to set Linker -> Advanced -> Entrypoint to test But I got lots of lnk2001 errors. Is it possible to somehow remove any main() wmain() WinMain() and use my function with just Visual studio settings?
Using a custom entry point in a Windows app bypasses the entire CRT startup and global C++ initializations. Because of that, it requires not using the CRT, and turning off compiler features that depend on the CRT such as /GS buffer checks and other /RTC run-time error checks.
The following is an example of a minimal app with the custom entry point test.
#include <sdkDdkVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// compile with /GS- lest
// LNK2001: unresolved external symbol #__security_check_cookie#4
//#pragma strict_gs_check(off)
// turn off /RTC*
#pragma runtime_checks("", off)
#pragma comment(linker, "/nodefaultlib /subsystem:windows /ENTRY:test")
int __stdcall test(void)
{
OutputDebugStringA("custom /entry:test\n");
ExitProcess(0);
}
More insight can be found in Raymond Chen's WinMain is just the conventional name for the Win32 process entry point.

Where shall I put a DLL generated in another project from the same solution -I am using Visual Basic Visual Studio 2017-?

I have created a C++ DLL in Visual Studio 2017 using the following sources:
Header: stdfax.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
// reference additional headers your program requires here
Header: targetver.h
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>
Source: stdafx.cpp
#include "stdafx.h"
Source: dll.cpp
// dll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
Source: dllmain.cpp
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Source: Source.cpp <- this is where I intend to add my source file
#include "stdafx.h"
#define EXPORTING_DLL
int HelloWorld(int A) {
return (2 * A);
}
Definition: Source.def <- Intentend to be able to consume this DLL from VB .NET
LIBRARY dll
DESCRIPTION 'A C++ dll tat can be called from VB'
EXPORTS
HelloWorld
Now I try to consume this DLL using a VB.NET project in the same solution:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("dll.dll", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Function HelloWorld(ByVal x As Int64) As Int64
End Function
Private Declare Function HelloWorld Lib "dll.dll" (int) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim j
j = HelloWorld(CInt(TextBox1.Text))
TextBox2.Text = j
End Sub
End Class
But I get:
System.DllNotFoundException: 'Unable to load DLL 'dll.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)'
EDIT: Following Vincent's comment about the possibility of this being a duplicate of Trouble adding my Visual-C++ DLL to my VB.NET windows forms GUI app I have checked that link and it does effectively tells how to add a DLL to a VB project. In that sense it is a duplicate, however, I have fixed that I find now the following error while trying to access the DLL:
System.BadImageFormatException: 'An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)'
I have also, following the side comment, modified my source file containing the function that needs to be exported to:
Source: Source.cpp <- this is where I intend to add my source file
#include "stdafx.h"
#define EXPORTING_DLL
extern "C" int HelloWorld(int A) {
return (2 * A);
}
I think that fixing that last issue, the question could be useful to others as it is a simple but documented "HelloWorld" example on how to build a DLL in C++ and consume it in VB.NET.

How can I check #ifdef in a DLL project, when the #define is in the executable project using the dll?

I have a C++ Visual Studio 2015 project consisting of
1 Windows API executable, 1 windows console executable, and 1 dll shared by both executables.
I have a #define USEWINDOWS in the Windows API main.cpp file
I don't have this defined in the console app
In the DLL, I would like to do an #ifdef USEWINDOWS statement, but the scope of the #define seems to be only valid to the Win32 executable, not in the dll.
How can I extend this #define to the DLL without having it affect the undefined USEWINDOWS in the console app?
Thanks
The DLL is shared by both executables, hence there is only one implementation available and therefore you can't use implementation specific compilation flags.
You'll need a runtime flag, i.e. some API parameter which tells the DLL code that it is OK to use "windows stuff". E.g.
api.h
void someAPI(...., bool useWindows);
dll.c
#include "api.h"
void someAPI(...., bool useWindows) {
...
if (useWindows) {
// do "windows stuff" here
}
...
}
app.c
#include "api.h"
...
someAPI(...., true);
console.c
#include "api.h"
...
someAPI(...., false);
(not tested by compilation, but you should get the drift...)

Injected DLL does nothing

I attempted to inject a C++ DLL in another WIN32 console programme. The injector (winjet) shows that it is successfully injected but the DLL itself does nothing.
As compiler I use Visual Studio 2013 and I just found out if I use precompiled header and this preset .cpp instead of a empty project without precompiled header, it works.
Dll.cpp :
BOOL APIENTRY Dllmain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
switch (reason) {
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "Attached!", "InjectedDLL", MB_OK);
}
return TRUE;
}
This code works with preset settings and precompiled header. But why it doesn't without that?
The entry point to a Windows DLL is called DllMain, not Dllmain.
You do not get a compile error for this (like when mis-spelling main), because it is optional.

MetaTrader4 close (crash?) on deinit() + dll threading on WinXP Mode Virtual PC

I have a native library built with Visual Studio 2012. Required project configuration properties:
General / Platform Toolset = Visual Studio 2012 - Windows XP (v110_xp)
C/C++ / Code Generation / Runtime Library = Multi-threaded (/MT)
ExpertSample.cpp:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mutex>
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) {
return(TRUE);
}
#define MT4_EXPFUNC __declspec(dllexport)
static std::mutex mutex;
MT4_EXPFUNC void __stdcall libInit() {
std::lock_guard<std::mutex> guard(mutex);
OutputDebugStringA("libInit");
}
MT4_EXPFUNC void __stdcall libDeInit() {
std::lock_guard<std::mutex> guard(mutex);
OutputDebugStringA("libDeInit");
}
ExpertSampleTest.mq4:
#import "ExpertSample.dll"
void libInit();
void libDeInit();
#import
int init() {
libInit();
return(0);
}
int deinit() {
libDeInit();
return(0);
}
int start() {
// libDeInit();
return(0);
}
Testing it on Windows 7 (x64) with MetaTrader build 451 (also for build 438) works normally.
Testing it in the WinXP Mode Virtual PC (running inside the same Windows 7), when the EA is removed from the chart, the whole terminal is closed. There is no crash report dialog, or anything in the log files.
If I call libDeInit() from start() it works fine.
If I remove the lock guard from libDeInit(), it works fine.
The above code is just a subset of a larger project. In that project, when the library was built with all kind of debug information and a lot of outputs, the problem seemed to happen less often.
Does anybody know how to fix it, or whether it's a MetaTrader 4 or WinXP Mode Virtual PC issue?
The C++ code itself looks good. Possible issues I see:
If the DLL is loaded but the constructor for the mutex is not called, that would explain your problem. That would be a problem in the environment loading the DLL.
Check the calling convention. Is it stdcall or cdecl? Using the wrong one can cause all kinds of issues, maybe even no issues under some circumstances.
Try replacing the mutex with a function returning a reference to a mutex, which is placed as function-static instance inside that function. If that helps, I'd say that it proves that the constructor is not called.
You don't need DllMain(), I'd only use it to call DisableThreadLibraryCalls().