如何从C++;到C#

如何从C++;到C#,c#,c++,dll,unmanaged,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 FRAP

我正在尝试从“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;
}
我不知道它在C中的等价物是什么#


完整代码可以在Use DllImport属性中找到,它将调用非托管DLL。只要找到必要的C库并从中调用适当的函数即可。 这里有一个非常有用的例子:

把它弄明白了。这是我如何管理的

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比我最初认为的要复杂得多。有一件事我不明白,我们首先要怎么弄清楚这个学生的结构

C++代码正在运行时加载DLL。GetProcAddress所做的只是获取一个指向它稍后要调用的DLL函数的指针。这是C++中不应该担心的所有C++的东西——只要在C语言中读到如何与第三方DLL接口——这是第一步。通常可以用<代码> DLimPult<代码>属性类实现这是一个复制品吗?这里有一些关于如何在C#@PaulMcKenzie中执行LoadLibrary/GetProcAddress的文章的有用链接:我认为他在C#中确实需要担心这个问题-如果当前安装的DLL是旧版本,则不能调用。MDK:出于同样的原因,我认为DllImport
DllImport
不会有多大帮助。@MartinBonner我不同意。OP的问题似乎表明试图理解动态绑定到DLL。虽然它被用于版本资格,但我不相信这是OP需要理解的,但是你提供的链接似乎是C++的。我找到了一个职位。可能和我的案子有关我刚才说的。没关系。它适用于C++和Sharp。但在DllImport属性中,放入您所需的DLL。设法从DLL中获取指向结构的指针。无法确定如何将返回的数据放入结构。这就是我目前拥有的结构,你可以在文档中找到,并用C#方式编写。然后从非托管库中设置函数,它将检查结构并填充它。@NikolaiArsenov所以没有办法“发现”结构或dll的结构?我想象会有某种逆向工程工具来展示这样的东西。我确信,确实有这样的工具。因为C#库的大部分功能都是由工具生成的。例如,SypPDX项目或SARPGL生成的包装,等于DirectX和OpenGL库,用于C++。见以下文章:以及
using System.Runtime.InteropServices;