I want call the ConsoleAppTwo.Program::PrintMessage the application...
i create a csharp test software with a function to call me:
using System;
namespace ConsoleAppTwo
{
class Program
{
static void PrintMessage(string str)
{
Console.WriteLine(str);
}
static void Main(string[] args)
{
while (true)
{
if(Console.ReadKey().Key == ConsoleKey.NumPad0)
{
PrintMessage("[Whatever string]");
}
}
}
}
}
and i use the IDA pro to found the functions:
IDA PRO
after i use the cheat engine and add the 'address' "ConsoleAppTwo.Program::PrintMessage" and get the address pointer and i create the dll:
#include <string>
#include <Windows.h>
#include "main.h">
using namespace std;
typedef void(__cdecl *_FuncA)(string str);
DWORD WINAPI MainThread(LPVOID param) {
_FuncA func = (_FuncA)(0x3504F0);
while (!GetAsyncKeyState(VK_HOME))
{
if (GetAsyncKeyState(VK_INSERT) & 1)
{
func("What is your name");
}
Sleep(10);
}
FreeLibraryAndExitThread((HMODULE) param, 0);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
CreateThread(0, 0, MainThread, GetModuleHandle(NULL), 0, 0);
default:
break;
}
return true;
}
and after i inject the dll in software and the code not work..., i get the output error: "EXCEPTION_ACCESS_VIOLATION"
Related
I achieved interoperability between C# & C++ using SWIG.
However, the C ++ to C # callback does not work properly.
If you pass "std::wstring" to the callback on the C++ side, it will be treated as a "string" on the C# side, but only the first character of the string passed on the C++ side will be stored.
My goal is using "std::string" in argument of callback.
Creating a base class with virtual function in C++ and derive a class in C# which implement the virtual method.
I referred to this link.
Callback from C++ to C# using SWIG
My code what callback from C++ to C# using SWIG is following.
C++ : Header.h
#include <string>
#include <vector>
class CallbackBase
{
public:
virtual void Callback(const std::wstring& str) = 0;
};
class CppClass
{
public:
void SetString(const std::wstring &str);
std::wstring GetString();
void SetCallback(CallbackBase& callbackObject);
void ExeCallback();
private:
std::wstring string;
CallbackBase* pCallbackObj = NULL;
void InvokeCallback();
};
typedef CppClass* (*GetInstanceFuncPointer)(void);
extern "C" __declspec(dllexport) CppClass * CreateInstance(void);
C++ : Impl.cpp
#include <thread>
#include "Header.h"
void CppClass::SetString(const std::wstring& str)
{
string = str;
}
std::wstring CppClass::GetString()
{
return string;
}
void CppClass::SetCallback(CallbackBase &callbackObj)
{
pCallbackObj = &callbackObj;
}
void CppClass::ExeCallback()
{
std::thread *th = new std::thread(&CppClass::InvokeCallback, this);
th->join();
}
void CppClass::InvokeCallback()
{
if (pCallbackObj != NULL)
{
pCallbackObj->Callback(string);
}
}
__declspec(dllexport) CppClass* CreateInstance(void)
{
return new CppClass;
}
Swig : Interface file
%include <windows.i>
%include <wchar.i>
%include <std_wstring.i>
%module (directors="1") MyDLL
%{
#include "Header.h"
%}
%feature("director") CallbackBase;
%include "Header.h"
C# : main.cs
using System.Diagnostics;
namespace CsharpApp
{
public class MyCallback : CallbackBase
{
public override void Callback(string str)
{
Debug.WriteLine($"str = {str}"); // --> str = H
}
}
class Program
{
static void Main(string[] args)
{
MyCallback myCallbackObj = new MyCallback();
CppClass instance = MyDLL.CreateInstance();
string str = "Hello World!";
instance.SetString(str);
Debug.WriteLine($"str = {instance.GetString()}"); // --> str = Hello World!
instance.SetCallback(myCallbackObj);
instance.ExeCallback();
}
}
}
I'm getting the string twice on the C# side.
The first is "GetString()" in the main function.
In this case, "Hello World!" Is stored.
The second time I get it as an argument of the callback function.
In this case, only "H" is stored.
How can I correctly store the string in the callback function argument?
I seem to be having issue with calling static C# methods.
I currently have 2 DLLs that I inject into an ancient legacy app and then execute a static method as seen in the code below:
Module.cs
using System;
namespace Debugger
{
public static class Module
{
public static void Initialize()
{
Console.WriteLine("YES");
}
}
}
dllmain.cpp
#include "stdafx.h"
#include <windows.h>
#pragma once
#pragma managed
using namespace System;
using namespace System::Reflection;
using namespace Debugger;
DWORD WINAPI MainThread(LPVOID param)
{
AllocConsole();
Console::WriteLine("Test");
Debugger::Module::Initialize();
FreeLibraryAndExitThread((HMODULE)param, 0);
return 0;
}
#pragma unmanaged
HMODULE hModule;
BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, MainThread, hModule, 0, 0);
break;
case DLL_PROCESS_DETACH:
FreeLibrary(hModule);
break;
}
return true;
}
As a result: I get the console open, the 'Test' message pops up but 'YES' doesn't - instead, the app crashes.
Moving the DLL to the same folder as executable I'm injecting into fixed the issue.
Hi i am having the same problem with abstract class.i am trying to wrap my cpp Dll calls to use in the C# module.
Dll is using the Factory pattern.which contain a class Factory,MiddileWare ,And their costrong textrresponding child class.Could any one help me to start the wrapper. i am stuck in between this.Your help will be appreciated. i am giving the flow here:
MiddleWareFactory.h
#pragma once
#include "MiddleWareConnection.h"
#include "std afx.h"
#ifdef MIDDLEWAREFACTORY_EXPORTS
#define MIDDLEWAREFACTORY_API __declspec(dllexport)
#else
#define MIDDLEWAREFACTORY_API __declspec(dllimport)
#endif
MIDDLEWAREFACTORY_API enum eMiddleWareEngine
{
eRabitMQ = 0,
eZeroMQ,
eActiveMQ
};
// This class is exported from the MiddleWareFactory.dll
class MIDDLEWAREFACTORY_API CMiddleWareFactory
{
public:
CMiddleWareFactory(void);
~CMiddleWareFactory();
// TODO: add your methods here.
//Function to Create the object of Broker module:implemnted the Factory concept.
BOOL CreateInstance(CMiddleWareConnection** pMObj);
int m_eMomEngine;//To define which MOM need to enable.
};
extern MIDDLEWAREFACTORY_API int nMiddleWareFactory;
MIDDLEWAREFACTORY_API int fnMiddleWareFactory(void);
MiddleWareConnection.h
#pragma once
class CMiddleWareConnection
{
public:
virtual ~CMiddleWareConnection(void)
{
}
//Pure virtual fuctions for interfacing
virtual BOOL Connect(int nServerType)=0;
virtual BOOL CreateSessionExchange() = 0;
virtual BOOL CreateQueue(LPCTSTR lpszQueueName) = 0;
virtual BOOL Disconnect() = 0;
virtual BOOL Send(void *MomItem,LPCTSTR lpszKey, int &nSendCount)=0;
virtual BOOL Receive() = 0;
virtual void StopReceiver() = 0;
virtual void GetData(void* pMsg, int &nMsgLen,int nMsgType,int &nReceiveCount)=0;
};
RabbitMQ.h
#pragma once
#include "MiddleWareConnection.h"
#include "Amqp.h"
#pragma comment(lib, "rabbitmq.4.lib")
#define GET_DATA(a){memcpy(&a, pDataPtr, sizeof(a));pDataPtr+=sizeof(a);}
#define GET_DATA_EX(s,n){memcpy(s, pDataPtr, n);pDataPtr+=n;}
typedef struct _ROUTINE_KEY
{
CString RoutingKey;
}ROUTEKEY, *LPROUTEKEY;
class CRabbitMQ :
public CMiddleWareConnection
{
public:
CRabbitMQ(CAppConfig &rConfig);
~CRabbitMQ();
void InitializeRBMQ(CAppConfig &rConfig);//Initialize RBMQ Config;
BOOL Connect(int nServerType);
BOOL Disconnect(void);
BOOL Send(void *MomItem, LPCTSTR lpszKey, int &nSendCount);
BOOL Receive(void);
BOOL CreateQueue(LPCTSTR lpszQueueName);
BOOL CreateSessionExchange();
BOOL BindQueue(LPCTSTR lpszQueue, LPCTSTR lpszExchangeName, LPCTSTR lpszKey);
bool IsConnected(){return m_bConnected;}
void SetKeyQueueCombination( TCHAR *pszQueueName, TCHAR *pszRoutingKey);
void StopReceiver();
bool ReEstablishRMQMWConnection();
void GetData(LPBYTE &pMsg, int &nMsgLen,int &nReceiveCount);
void GetData(void* pMsg, int &nMsgLen,int nMsgType,int &nReceiveCount);
BOOL GetNext_JasonListItem(LPJASON_ITEM pItem);
LPRABBIT_MQ_ITEM GetNextItem();
};
Here i want to expose the rabbitMq class functions[Connect,send,Recieve ete from MiddleWareConnection.h to C# module.
Thanks
below I posted a small code example of a wrapping C++/CLI class. You could create a new C++/CLI project which links your native library and create a class following the example below. This will produce a managed assembly that you could reference from C# side. Hope it helps!
#include <Windows.h>
#include <vcclr.h>
using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
public ref class CMiddleWareConnection_Net
{
public:
CMiddleWareConnection_Net()
{
pMiddleWareConnection = NULL;
}
~CMiddleWareConnection_Net()
{
//Release pMiddleWareConnection
if (pMiddleWareConnection)
delete pMiddleWareConnection;
}
void InitializeRBMQ(CAppConfig_Net config)
{
// CAppConfig_Net is another ref class
// which provides a toNative method
// returning a plain C++ CAppConfig object
CAppConfig rConfig = config.toNative();
pMiddleWareConnection = CRabbitMQ(rConfig);
}
bool Connect(int nServerType)
{
return (pMiddleWareConnection->Connect(nServerType) == TRUE);
}
bool Disconnect(void)
{
return (pMiddleWareConnection->Disconnect() == TRUE);
}
bool Send(array<Byte>^ MomItem, String^ lpszKey, int% nSendCount)
{
//Assuming MomItem is a byte array...
unsigned char *pData = new unsigned char[MomItem->Length];
Marshal::Copy(MomItem, 0, IntPtr(pData), MomItem->Length);
//Marshal String^ to LPCSTR
IntPtr ip = Marshal::StringToHGlobalAnsi(lpszKey);
LPCSTR str = static_cast<LPCSTR>(ip.ToPointer());
bool bRet = (pMiddleWareConnection->Send(pData, str, nSendCount) == TRUE);
//Freeing memory
delete[] pData;
Marshal::FreeHGlobal(ip);
return bRet;
}
bool Receive(void)
{
return (pMiddleWareConnection->Receive() == TRUE);
}
/* Other methods */
...
private:
CMiddleWareConnection *pMiddleWareConnection;
};
****MiddleWareFactory.h****
BOOL CreateInstance(CMiddleWareConnection** pMObj)
{
//if( some config value)
*pMObj = new RabbitMq();
// esle
/***other MOm like OBCS,OSCS etec...**/
}
****MiddlewareConnection.h****
have the basic abstract functions....
**Rabbitmq.h**
it is one of the child class.
****Wrapper****
CLRWrapper::CppMathWrapper::CppMathWrapper()
{
cppMath = new cCppMath();
oFact->createInstance(&cppMath);'// here i want to pass the reference & wanna get back the child class type:now i am stuck here..how can we pass/marshal the object:im getting the error
}
BOOL CLRWrapper::CppMathWrapper::connect(type)
{
return (cppMath->Connect(nServerType) == TRUE);
}
..........And so On............
CLR Wrapper.cpp(11) : error C2664: 'Factory::createInstance' : cannot convert parameter 1 from 'cli::interior_ptr' to 'Base **'
1> with
1> [
1> Type=cCppMath *
1> ]
1> Cannot convert a managed type to an unmanaged type
}
instead of this we are using createinstance()[InitializeRBMQ() is inside connect(),so it will be handled inside i think]
void InitializeRBMQ(CAppConfig_Net config)
{
// CAppConfig_Net is another ref class
// which provides a toNative method
// returning a plain C++ CAppConfig object
CAppConfig rConfig = config.toNative();
pMiddleWareConnection = CRabbitMQ(rConfig);
}
C# side
i want to expose :
private static void Main(string[] args)
{
CppMathWrapper wrapper = new CppMathWrapper();
wrapper.connect(0);
}
i tried one example with CPPMath class.In real i am attaching the code below:
CLRWrapper::CppMathWrapper::CppMathWrapper()
{
middlewareConnection *oConn;// MiddleConnection.h pointer
middleWareFactory oFact= new middleWareFactory ();// MiddleWareFactory.h object
oFact->createInstance(&oConn);'// here i want to pass the reference & wanna get back the child class type:now i am stuck here..how can we pass/marshal the object:im getting the error.How could i wrap the object....the same like
}
BOOL CLRWrapper::CppMathWrapper::connect(type)
{
return (oConn->Connect(nServerType) == TRUE);
}
..........And so On............
say I have a C++ library function for computing PI:
// pi.h:
#ifdef BUILDING_DLL
#define DLL_MACRO __declspec(dllexport)
#else
#define DLL_MACRO __declspec(dllimport)
#endif
namespace Cpp {
class PI {
public:
static double DLL_MACRO compute();
};
};
// pi.cpp:
#include "pi.h"
#include <cmath>
double
Cpp::PI::compute() {
// Leibnitz summation formulae:
double sum = 0.0;
for(long n = 0; n < 100*1000*1000; n++)
sum += 4.0*pow(-1.0, n)/(2*n + 1.0);
return sum;
}
I need to call this function from C#, and I want to use C++/CLI as a "bridge". However this C++ function is somewhat slow. Therefore the C# code calling this function need to get callbacks telling it how far the function has come in %.
The C# code might need some state, e.g. a progress bar, to deal with this info.
So the callbacks from C++ must enter into a member function on the C# side.
So I introduce:
// piCLI.h: The C++/CLI "bridge" between C# and C++
#include "pi.h"
#pragma once
namespace CLI {
public ref class PI abstract {
public:
double compute() {
return Cpp::PI::compute();
}
virtual void progress(int percentCompleted) = 0;
};
};
and
namespace CSharp
{
public class PI : CLI.PI
{
public override void progress(int percentCompleted)
{
System.Console.WriteLine(percentCompleted + "% completed.");
}
}
}
Now invoking CSharp.PI.compute() works fine :-). It forwards the call to Cpp::PI::compute() as intended.
But how do I get the C++ library to forward progress updates to CSharp.PI.progress() whilst Cpp::PI::compute() is running?
Thanks in advance for any answers!
I would take a function pointer/delegate approach as well:
// pi.h:
#pragma once
#ifndef DLL_MACRO
#ifdef BUILDING_DLL
#define DLL_MACRO __declspec(dllexport)
#else
#define DLL_MACRO __declspec(dllimport)
#endif
#endif
namespace Cpp {
typedef void (__stdcall *ComputeProgressCallback)(int);
class PI {
public:
static double DLL_MACRO compute(ComputeProgressCallback callback);
};
}
// pi.cpp:
#include "pi.h"
#include <cmath>
double Cpp::PI::compute(Cpp::ComputeProgressCallback callback) {
double sum = 0.;
for (long n = 0L; n != 100000000L; ++n) {
sum += 4. * std::pow(-1., n) / (2L * n + 1.);
callback(/*impl*/);
}
return sum;
}
// piCLI.h: The C++/CLI "bridge" between C# and C++
#pragma once
#include "pi.h"
namespace CLI {
public delegate void ComputeProgressDelegate(int percentCompleted);
public ref class PI abstract sealed {
public:
static double compute(ComputeProgressDelegate^ callback) {
using System::IntPtr;
using System::Runtime::InteropServices::Marshal;
IntPtr cbPtr = Marshal::GetFunctionPointerForDelegate(callback);
return Cpp::PI::compute(
static_cast<Cpp::ComputeProgressCallback>(cbPtr.ToPointer())
);
}
};
}
namespace CSharp {
public static class PI {
public static double compute() {
CLI.PI.compute(
percentCompleted => System.Console.WriteLine(
percentCompleted.ToString() + "% completed."
)
);
}
}
}
Or, to override an abstract progress method rather than creating a delegate on the C# side:
// piCLI.h: The C++/CLI "bridge" between C# and C++
#pragma once
#include "pi.h"
namespace CLI {
public ref class PI abstract {
delegate void ComputeProgressDelegate(int percentCompleted);
public:
double compute() {
using System::IntPtr;
using System::Runtime::InteropServices::Marshal;
ComputeProgressDelegate^ callback = gcnew ComputeProgressDelegate(
this,
&PI::progress
);
IntPtr cbPtr = Marshal::GetFunctionPointerForDelegate(callback);
return Cpp::PI::compute(
static_cast<Cpp::ComputeProgressCallback>(cbPtr.ToPointer())
);
}
protected:
virtual void progress(int percentCompleted) abstract;
};
}
namespace CSharp {
public sealed class PI : CLI.PI {
protected override void progress(int percentCompleted) {
System.Console.WriteLine(
percentCompleted.ToString() + "% completed."
);
}
}
}
Pass a C++/cli defined Native function to your native C++ as a callback and upon callback use a gcroot to call your managed C# function.
developers!
I have very strange problem. My project has DLL writen in C++ and a GUI writen in C#. And I have implemented callback for some interoperability. I planed that C++ dll will call C# code in some circumstances. It works... but not long and I cant understand why. The problem marked in comment in C# part
Here the complete code of simplified sample:
C++ DLL:
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.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;
}
extern "C"
{
typedef void (*WriteSymbolCallback) (char Symbol);
WriteSymbolCallback Test;
_declspec(dllexport) void InitializeLib()
{
Test = NULL;
}
_declspec(dllexport) void SetDelegate(WriteSymbolCallback Callback)
{
Test = Callback;
}
_declspec(dllexport) void TestCall(const char* Text,int Length)
{
if(Test != NULL)
{
for(int i=0;i<Length;i++)
{
Test(Text[i]);
}
}
}
};
C# part:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CallBackClient
{
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void WriteToConsoleCallback(char Symbol);
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void InitializeLib();
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void SetDelegate(WriteToConsoleCallback Callback);
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void TestCall(string Text,int Length);
private static void PrintSymbol(char Symbol)
{
Console.Write(Symbol.ToString());
}
static void Main(string[] args)
{
InitializeLib();
SetDelegate(new WriteToConsoleCallback(PrintSymbol));
string test = "Hello world!";
for (int i = 0; i < 15000; i++)
{
TestCall(test, test.Length);// It crashes when i == 6860!!!! Debugger told me about System.NullReferenceException
}
}
}
}
The problem is that it crashes in 6860th iteration! I believe that the problem is lack of my knowlege in the subject. Could sombody help me?
SetDelegate(new WriteToConsoleCallback(PrintSymbol));
Yes, this cannot work properly. The native code is storing a function pointer for the delegate object but the garbage collector cannot see this reference. As far as it is concerned, there are no references to the object. And the next collection destroys it. Kaboom.
You have to store a reference to the object yourself. Add a field in the class to store it:
private static WriteToConsoleCallback callback;
static void Main(string[] args)
{
InitializeLib();
callback = new WriteToConsoleCallback(PrintSymbol);
SetDelegate(callback);
// etc...
}
The rule is that the class that stores the object must have a lifetime at least as long as native code's opportunity to make the callback. It must be static in this particular case, that's solid.