Reputation: 101
I'm trying to get the FPS data from "Fraps". There is a project called LCDHost on github which has done this. Apparently it's done by hooking to "fraps.dll"
I need to port this code to a C# project i'm working on. Problem is I'm not good at C++ and haven't got any experience in accessing unmanaged dlls from C#.
If someone can give me pointers on how to convert this code to C#, I'd appreciate that.
#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;
}
The line that really stumped me is this one
FrapsSharedData = (typeof(FrapsSharedData)) GetProcAddress(frapsDLL, "FrapsSharedData");
I don't know what's the equivalent of it in C#
The full code can be found here
Upvotes: 1
Views: 630
Reputation: 101
Figured it out. Here is how I managed.
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;
}
}
}
And at the top you need to
using System.Runtime.InteropServices;
Using unmanaged DLLs in C# code is far more complicated then I initially thought. One thing I don't understand, how do we figure out the stuct's structure in the first place?
Upvotes: 0
Reputation: 464
Use DllImport Attribute and it will call an unmanaged dlls. Just find the necessary C library call an appropriate function from it. Very useful example is there: https://msdn.microsoft.com/en-us/library/aa984739(v=vs.71).aspx
Upvotes: 3