Home > Software engineering >  Unable to call dynamic library in Unity 3D
Unable to call dynamic library in Unity 3D

Time:09-13

Wrote a library for displaying system messages in C

.h

#pragma once

#ifndef WINDOW_DEFINDE_DEBUG
#define WINDOW_DEFINDE_DEBUG

#include <Windows.h>
#include <string>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef BUILD_LIBRARY
#define SHARED_LIBRARY_DECLSPEC __declspec(dllexport)
#else
#define SHARED_LIBRARY_DECLSPEC __declspec(dllimport)
#endif

    int SHARED_LIBRARY_DECLSPEC DebugWindowInformation(std::string message, std::string caption);
    int SHARED_LIBRARY_DECLSPEC DebugWindowQuestion(std::string message, std::string caption);
    int SHARED_LIBRARY_DECLSPEC DebugWindowWarning(std::string message, std::string caption);
    int SHARED_LIBRARY_DECLSPEC DebugWindowError(std::string message, std::string caption);

#ifdef __cplusplus
}
#endif

#endif

.cpp

#include "window_debug.h"

#define BUILD_LIBRARY

int SHARED_LIBRARY_DECLSPEC DebugWindowInformation(std::string message, std::string caption)
{
    std::wstring _message = std::wstring(message.begin(), message.end());
    std::wstring _caption = std::wstring(caption.begin(), caption.end());

    return MessageBox(NULL, (LPCWSTR)_message.c_str(), (LPCWSTR)_caption.c_str(),
        MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);
}

int SHARED_LIBRARY_DECLSPEC DebugWindowQuestion(std::string message, std::string caption)
{
    std::wstring _message = std::wstring(message.begin(), message.end());
    std::wstring _caption = std::wstring(caption.begin(), caption.end());

    return MessageBox(NULL, (LPCWSTR)_message.c_str(), (LPCWSTR)_caption.c_str(),
        MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON3);
}

int SHARED_LIBRARY_DECLSPEC DebugWindowWarning(std::string message, std::string caption)
{
    std::wstring _message = std::wstring(message.begin(), message.end());
    std::wstring _caption = std::wstring(caption.begin(), caption.end());

    return MessageBox(NULL, (LPCWSTR)_message.c_str(), (LPCWSTR)_caption.c_str(),
        MB_ICONWARNING | MB_OK | MB_DEFBUTTON1);
}

int SHARED_LIBRARY_DECLSPEC DebugWindowError(std::string message, std::string caption)
{
    std::wstring _message = std::wstring(message.begin(), message.end());
    std::wstring _caption = std::wstring(caption.begin(), caption.end());

    return MessageBox(NULL, (LPCWSTR)_message.c_str(), (LPCWSTR)_caption.c_str(),
        MB_ICONERROR | MB_OK | MB_DEFBUTTON1);
}

I'm trying to call the library functions through Unity, nothing happens. No errors, nothing at all. Maybe I'm doing something wrong?

C#

namespace Assets.Scripts.InvokeCallFunc
{
    public static class CallFunc
    {
        [DllImport(@"C:\Users\mrxit\Downloads\King Of Kings 3\Project\eh_handler32_64.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern int DebugWindowInformation([MarshalAs(UnmanagedType.BStr)] string message, [MarshalAs(UnmanagedType.BStr)] string caption);

        [DllImport(@"C:\Users\mrxit\Downloads\King Of Kings 3\Project\eh_handler32_64.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern int DebugWindowQuestion([MarshalAs(UnmanagedType.BStr)] string message, [MarshalAs(UnmanagedType.BStr)] string caption);

        [DllImport(@"C:\Users\mrxit\Downloads\King Of Kings 3\Project\eh_handler32_64.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern int DebugWindowWarning([MarshalAs(UnmanagedType.BStr)] string message, [MarshalAs(UnmanagedType.BStr)] string caption);

        [DllImport(@"C:\Users\mrxit\Downloads\King Of Kings 3\Project\eh_handler32_64.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern int DebugWindowError([MarshalAs(UnmanagedType.BStr)] string message, [MarshalAs(UnmanagedType.BStr)] string caption);
    }
}

Later, I try to call these functions in my code. For a test. Nothing comes out in the messages on Unity. I threw the library into Assets and into the root project and into Plugins. All the same.

CodePudding user response:

C# cannot marshal System.String as std::string because there different classes.

UnmanagedType.BStr in C# is BSTR in Windows SDK.

And you've set SetLastError = true, so when nothing comes out, you should call Marshal.GetLastWin32Error to get error.

In fact you can use this method to call MessageBox.

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
  • Related