WPF C# 应用程序中的 C++ Dll

C++ Dll in WPF C# application

在寻找已经针对与我的类似问题提出的解决方案后, 由于这是我第一次在 .NET 应用程序中使用非 .NET DLL, 我真的需要你的帮助。

我有一个 WPF 应用程序,使用 MVVM 模式,在我的 ViewModel class 中,我需要使用用 C++ 完成的 DLL 来恢复令牌。我在 C++ 中有一个使用此 DLL 的示例,因此我有方法的名称,但我不能在 C# 中执行相同的操作。我知道我必须使用 DllImport 才能使用此方法,但如何实现它并在 C# 中使用指针??

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>

int main()
{
    HINSTANCE hinst = NULL;

    typedef bool ( *GetTokenProto )( char ** );
    typedef void ( *FreeTokenProto )( char * );

    GetTokenProto GetToken;
    FreeTokenProto FreeToken;

    std::string str = "DllName.dll";
    std::string token;

    if ( (hinst = LoadLibraryA(str.c_str()) ) )
    {
        GetToken = (GetTokenProto) GetProcAddress(hinst, "GetToken");
        FreeToken = (FreeTokenProto) GetProcAddress(hinst, "FreeToken");

        if (GetToken && FreeToken)
        {
            char *buf;
            if (GetToken(&buf))
            {
                token = buf;
                FreeToken(buf);

                std::cout << "Token:" << token << std::endl;
            }
            else
            {
                std::cerr << "DLL loaded but no token" << std::endl;
                exit(1);
            }
        }
        else
        {
            std::cerr << "DLL loaded but missing proc address(es)" << std::endl;
            exit(1);
        }

        FreeLibrary(hinst);
    }
    else
    {
        std::cerr << "Failed to load DLL" << std::endl;
        exit(1);
    }
    return 0;
}

更新

[DllImport("DllName.dll", EntryPoint = "GetToken", CallingConvention = CallingConvention.Cdecl)] 
public static extern bool get_token(ref string token); 

[DllImport("DllName.dll", EntryPoint = "FreeToken", CallingConvention = CallingConvention.Cdecl)] 
public static extern void free_token(ref string token);

public static string a_token; 
public string get_token_method() 
{ 
    try 
    { 
        string buffer = null; 
        if (get_token(ref buffer)) 
        { 
            a_token = buffer; 
            free_token(ref buffer); 
            Debug.WriteLine("token : " + a_refresh_token); 
        } 
        else 
        { 
            Debug.WriteLine("DLL Loaded but no token"); 
        } 
    } 
    catch (Exception ex) 
    { 
       Debug.WriteLine("\n" + ex.Message); 
    } 
    return a_refresh_token; 
}

错误

I have an Exception "System.DllNotFoundException" : Unable to load DLL 'DllName.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E).

Dll 文件与 .exe (..\bin\Debug) 在同一个文件夹中

如果您的 DLL 在同一个目录中,仍有一些问题可能是问题所在。

首先

Dll 可能有依赖项

The native DLL you use may have other dependencies which have to be installed (try Dependency Walker). If the native DLL requires for example registry settings, config files etc. these should also be present. It should be distributed to user machines the same way you installed it on the dev machine.

很可能您缺少 C++ 可再发行组件包(我不是父亲)怎么 Dependency Walker 应该告诉您

其次

它可能针对不同的位数,即 x86 x64,所以我尝试更改您的项目以查看是否有帮助

  • Right click your project, and select properties.

  • In properties, select the build tab. Under platform target, select x86.

  • Hit Ctrl+Shift+S to save all files, right click the solution and select "Clean" to get rid of old binaries. Any builds after that should be 32 bit

您可以使用 SetDllDirectory 方法在调用您的 dll 之前设置您的 dll 的路径

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);

如果你想从 C++ 获取字符串,你也应该在 C# 端使用 StringBuilder 而不是字符串。