如何将DLL访问代码从C ++移植到C#

时间:2016-05-13 20:16:28

标签: c# c++ dll unmanaged

我正在尝试从“Fraps”获取FPS数据。在github上有一个名为LCDHost的项目就是这样做的。显然它是通过挂钩“fraps.dll”

来完成的

我需要将此代码移植到我正在处理的C#项目中。问题是我不擅长C ++,也没有从C#访问非托管dll的经验。

如果有人可以指点我如何将此代码转换为C#,我会很感激。

#include <stdio.h>
#include <windows.h>

#include "LH_Text.h"

struct FRAPS_SHARED_DATA {
   DWORD sizeOfStruct;
   DWORD currentFPS;
   DWORD totalFrames;
   DWORD timeOfLastFrame;
   char gameName[32];
};

FRAPS_SHARED_DATA *(WINAPI *FrapsSharedData) ();    
int notify(int n,void* p)
{
    if( !n || n&LH_NOTE_SECOND )
    {
        HMODULE frapsDLL;
        FRAPS_SHARED_DATA *fsd;
        frapsDLL = GetModuleHandleA("FRAPS32.DLL");
        if (!frapsDLL) {
            if( setText("N/A") ) callback(lh_cb_render,NULL);
        } else {
            FrapsSharedData = (typeof(FrapsSharedData)) GetProcAddress(frapsDLL, "FrapsSharedData");
            if (!FrapsSharedData) {
                if( setText("Needs Fraps 1.9C or later!") ) callback(lh_cb_render,NULL);
            } else {
                if( setText( "Fraps is running & is the right version." ) ) callback(lh_cb_render,NULL);
                fsd = FrapsSharedData();
                if( setText(QString::number(fsd->currentFPS) ) ) callback(lh_cb_render,NULL);
            }
        }
    }
    return LH_Text::notify(n,p) | LH_NOTE_SECOND;
}

真正困扰我的那条线就是这一条

FrapsSharedData = (typeof(FrapsSharedData)) GetProcAddress(frapsDLL, "FrapsSharedData");

我不知道它在C#中的等价物是什么

可以找到完整的代码here

2 个答案:

答案 0 :(得分:2)

使用DllImport属性,它将调用非托管dll。只需从中找到必要的C库调用适当的函数即可。 非常有用的例子是: https://msdn.microsoft.com/en-us/library/aa984739(v=vs.71).aspx

答案 1 :(得分:0)

想出来。这是我管理的方式。

class fraps
{
    [StructLayout(LayoutKind.Sequential)]
    public struct sFraps
    {
        public int SizeOfStruct;
        public int CurrentFPS;
        public uint TotalFrames;
        public uint TimeOfLastFrame;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public char[] GameName;

    };

    [DllImport("FRAPS32.dll")]
    public static extern IntPtr FrapsSharedData();

    public int fpsGet() {
        try
        {
            sFraps fps = (sFraps)Marshal.PtrToStructure(FrapsSharedData(), typeof(sFraps));
            return fps.CurrentFPS;
        }
        catch
        {
            return -1;
        }


    }
}

在顶部你需要

using System.Runtime.InteropServices;

在C#代码中使用非托管DLL比我最初想的要复杂得多。有一点我不明白,我们如何首先弄清楚结构的结构?