Reputation: 3125
I have a WPF / c# application that uses Log4Net for logging. This application calls a few c++ dlls using:
[DllImport("test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestFunction();
What I would like to do is have the dlls send logging messages back to the C# application, so that everything from both c++ and c# go to the same log. Is this possible?
If so, how can i go about it?
Upvotes: 3
Views: 829
Reputation: 1794
An example that redirect logs in c++ dill to c# callback:
c# side:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void LogCallback([MarshalAs(UnmanagedType.LPWStr)] string info);
namespace WinApp
{
static class Wrapper
{
[DllImport("target.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern void SetLogCallback([MarshalAs(UnmanagedType.FunctionPtr)] LogCallback callbackPointer);
internal static void Init()
{
LogCallback log_cb = (info) =>
{
Console.Write(DateTime.Now.TimeOfDay.ToString() + " " + info);
};
SetLogCallback(log_cb);
}
}
c++ side( compiled in target.dll
):
extern "C" {
typedef char* (__stdcall* LogCallback)(const wchar_t* info);
PEPARSER_API void SetLogCallback(LogCallback cb);
}
static LogCallback global_log_cb = nullptr;
void LogInfo(const wchar_t* info) {
if (global_log_cb) {
std::wstring buf = L"[PEParse]" + std::wstring(info) + L"\n";
global_log_cb(buf.c_str());
}
else {
std::cout << "global_log_cb not set\n";
}
}
void LogInfo(const char* info) {
const size_t cSize = strlen(info) + 1;
size_t t;
std::wstring wstr(cSize, L'#');
mbstowcs_s(&t, &wstr[0], cSize, info, cSize - 1);
LogInfo(&wstr[0]);
}
void SetLogCallback(LogCallback cb) {
global_log_cb = cb;
LogInfo("log init");
}
I have been using this interface for long times.
Upvotes: 3