如何解决“EntryPointNotFoundException”

问题描述 投票:0回答:1

我试图导入外部C ++方法为我的C#代码。

我已经修改了它我使用访问内存中的Windows驱动程序。要调用驱动程序,我使用C ++接口。最后,调用我连接到驱动器的接口,我使用C#代码。

我现在面临的问题是,在运行过程中,我得到以下错误System.EntryPointNotFoundException:无法找到名为“GetTargetPid”在DLL“API.dll”的切入点。

现在,接口本身只包含一个头文件中。我想,也许这就是问题所在,但是从我在线阅读,使用甚至实现完美的罚款单的头文件。

这是我在C#进口

[DllImport("API.dll")]
public static extern IntPtr GetTargetPid();

这里我调用方法

IntPtr processID = IntPtr.Zero;
...
ProcessID = GetTargetPid();

所以,我的C#代码是没有什么特别的。

现在,这里是我的API.dll

extern "C"
{
...
class CDriver
{
public:
    //Handle to the driver
    HANDLE hDriver; 
    //Initialization of the handle              
    CDriver::CDriver(LPCSTR RegistryPath)
    {
        hDriver = CreateFileA(RegistryPath, GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
    }
    ...

    __declspec(dllexport)
    ULONG_PTR GetTargetPid()
    {
        if (hDriver == INVALID_HANDLE_VALUE)
            return false;

        PVOID Id = 0;
        ULONG_PTR Result;
        DWORD Bytes;

        if (DeviceIoControl(hDriver, IO_GET_PROCESS_ID, NULL, NULL,
            Id, sizeof(Id), &Bytes, NULL)) {

            Result = (ULONG_PTR)Id;
            return Result;
        }

        else
            return false;
    }

大多数的心中已经在线阅读使用静态方法的例子,是任何重要?我需要的是进口的工作是什么,我想这应该是微不足道的,但是我不能弄明白。

c# c++ pinvoke calling-convention
1个回答
2
投票

你有两个问题。第一个问题__declspec(dllexport) ULONG_PTR GetTargetPid()编译就好了,出口CDriver::GetTargetPid。你不希望出现这种情况。

在阅读您的CDriver代码我相信,它不是一个单例。如果你真的想的P / Invoke:

extern "C" {
__declspec(dllexport)
CDriver *CreateCDriver(LPCSTR RegistryPath)
{
    return new CDriver(RegistryPath);
}

__declspec(dllexport)
ULONG_PTR GetTargetPid(CDriver *driver)
{
    return driver->GetTargetPid();
}

__declspec(dllexport)
CDriver *DestroyCDriver(CDriver *driver)
{
    delete driver;
}
} // extern "C"

问题二:你是P /调用C函数。需要在C#中CDECL声明:

[DllImport("API.dll", CallingConvention=Cdecl, CharSet=CharSet.????)]
public static extern IntPtr CreateCDriver(string name);

[DllImport("API.dll", CallingConvention=Cdecl)]
public static extern IntPtr GetTargetPid(IntPtr cdriver);

[DllImport("API.dll", CallingConvention=Cdecl)]
public static extern IntPtr DestroyCDriver(IntPtr cdriver);

我无法从你的代码告诉您是否编译ANSI或Unicode;填写字符集。????正确。

这东西的用法是这样的:

IntPtr cdriver = null;
try {
    cdriver = CreateCDriver("whatever");
    var pid = GetTargetPid(cdriver);
    // do whatever with pid
} finally {
    DestroyCDriver(cdriver);
}

那一刻,你必须移动cdriver参考关闭你需要Dispose()Finalize()堆栈。

internal class CDriver : IDisposable {
    private IntPtr cdriver;

    public CDriver(string registry)
    {
        cdriver = CreateCDriver("whatever");
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SupressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        DestroyCDriver(cdriver);
        cdriver = IntPtr.Zero;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.