Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

C++ How to call a function / Edit a value in c++ from c#

TableFlipGod

Bronze Coder
So currently I have a project that wraps around this open source program : Here.

And I want my form radio button to set the cap to 30 fps or 60 fps. There is a config type thing in the code shown here
[CODE title="Code" highlight="34-38, 8-20"]#include <d3d11.h>
#pragma comment(lib, "d3d11.lib")

#include "sigscan.h"
#include "../injector/mapping.h"

#pragma pack(push, 1)
extern struct SettingsIPC
{
bool vsync_enabled;
double fps_cap;

struct
{
int scan_result;
void *scheduler;
int sfd_offset;
int present_count;
} debug;
};
#pragma pack(pop)

HMODULE MainModule = NULL;
HANDLE SingletonMutex = NULL;
uintptr_t TaskScheduler = 0;
int TaskSchedulerFrameDelayOffset = 0;
FileMapping IPC;

extern void WINAPI DllInit();
void WINAPI DllExit();



extern void SetFPSCap(int cap)
{
SettingsIPC fpscapper;
fpscapper.fps_cap = cap;
}

inline SettingsIPC* GetIPC()
{
return IPC.Get<SettingsIPC *>();
}[/CODE]


I also get this error when running a function:

System.EntryPointNotFoundException: 'Unable to find an entry point named 'SetFPSCap' in DLL 'rbxfpsunlocker.dll'.'

Code:
[DllImport("rbxfpsunlocker.dll", CallingConvention = CallingConvention.Winapi)]
        static extern void SetFPSCap(int cap);



I have no idea how to set these values from c# using dll import. I did try to make a function as you can see from extern void SetFPSCap(int cap) that it failed horribly.


So how would i run functions from c#?
 
Last edited:
For me that's outside my comfort zone. I have the shims for Starcraft and Diablo but GOG currently have Diablo for sale .. maybe they've done the same thing for their release and have a shim DLL to get Diablo running. You could potentially use those things as references for investigating how an application uses the DirectX library for example. Maybe you could insert a shim DLL and log how the DirectX layer is being used.

Do you have empty functions for DllInit and DllExit?
Wdym “empty”? Ill show you more code when I get home
 
I also took a look at that and it didn’t help my case
That's just some light reading for how win32 deals with loading DLL functions via the LoadLibrary() win32 API.

Wdym “empty”? Ill show you more code when I get home
Example:
Code:
// this is a function prototype
void DllInit();
// this is an empty function
void DllInit()
{
}
The difference is that the first one declares (damn italics) that the function exists somewhere in the compilation, but does not define (damn italics again) the function.
 
Example:
Code:
// this is a function prototype
void DllInit();
// this is an empty function
void DllInit()
{
}
The difference is that the first one declares (damn italics) that the function exists somewhere in the compilation, but does not define (damn italics again) the function.
No, I do not have an empty function.
 
Oh move my code to a new function then make that function public after that just empty my DllInit function. And then problem solved?
Uh, it's more that if you declare a function as existing:
Code:
__declspec(dllexport) void DllInit();
You should have the actual function too:
Code:
__declspec(dllexport) void DllInit()
{
}
 
So make an empty function?

Here is the code btw
[CODE lang="cpp" title="main.cpp"]#include <Windows.h>

#include <string>
#include <iostream>
#include <vector>

#include <d3d11.h>
#pragma comment(lib, "d3d11.lib")

#include "sigscan.h"
#include "../injector/mapping.h"

#pragma pack(push, 1)



extern struct SettingsIPC
{
bool vsync_enabled;
double fps_cap;

struct
{
int scan_result;
void* scheduler;
int sfd_offset;
int present_count;
} debug;
};
#pragma pack(pop)

HMODULE MainModule = NULL;
HANDLE SingletonMutex = NULL;
uintptr_t TaskScheduler = 0;
int TaskSchedulerFrameDelayOffset = 0;
FileMapping IPC;


void WINAPI DllInit();
void WINAPI DllExit();



inline SettingsIPC* GetIPC()
{
return IPC.Get<SettingsIPC*>();
}

bool WriteMemory(void* address, const void* patch, size_t sz)
{
DWORD protect;

if (!VirtualProtect(address, sz, PAGE_EXECUTE_READWRITE, &protect)) return false;
memcpy((void*)address, patch, sz);
if (!VirtualProtect(address, sz, protect, (PDWORD)& protect)) return false;

return true;
}

void* HookVFT(void* object, int index, void* targetf)
{
int* vftable = *(int**)(object);
void* previous = (void*)vftable[index];

WriteMemory(vftable + index, &targetf, sizeof(void*));

return previous;
}

enum
{
Roblox,
RobloxStudio,
Win10,
Invalid
} Platform;

void DetectPlatform()
{
/* Get ProcessName */
char FileName[MAX_PATH];
GetModuleFileNameA(NULL, FileName, sizeof(FileName));

if (strstr(FileName, "RobloxPlayerBeta.exe"))
Platform = Roblox;
else if (strstr(FileName, "RobloxStudioBeta.exe"))
Platform = RobloxStudio;
else if (strstr(FileName, "Win10Universal.exe"))
Platform = Win10;
else
{
Platform = Invalid;
MessageBoxA(NULL, "Unknown platform", "Error", MB_OK);
DllExit();
}
}

uintptr_t FindTaskScheduler()
{
uintptr_t result;

try
{
result = (uintptr_t)sigscan::scan(NULL, "\x55\x8B\xEC\xE8\x00\x00\x00\x00\x8A\x4D\x08\x83\xC0\x04\x86\x08\x5D\xC3", "xxxx????xxxxxxxxxx"); // 55 8B EC E8 ?? ?? ?? ?? 8A 4D 08 83 C0 04 86 08 5D C3

if (result)
{
typedef uintptr_t(*GetTaskSchedulerFn)();
GetTaskSchedulerFn GetTaskScheduler = (GetTaskSchedulerFn)(result + 8 + *(uintptr_t*)(result + 4)); // extract offset from call instruction

GetIPC()->debug.scan_result = (int)GetTaskScheduler - (int)GetModuleHandleA(NULL);

result = GetTaskScheduler();
}
}
catch (...)
{
result = 0;
}

return result;
}

int FindTaskSchedulerFrameDelayOffset(uintptr_t scheduler)
{
/* Find the frame delay variable inside TaskScheduler (ugly, but it should survive updates unless the variable is removed or shifted) (variable was at +0x228 as of 10/11/2018) */
for (int i = 0x200; i < 0x300; i += 4)
{
static const double frame_delay = 1.0 / 60.0;
double difference = *(double*)(scheduler + i) - frame_delay;
difference = difference < 0 ? -difference : difference;
if (difference < 0.004) return i;
}

return 0;
}

typedef HRESULT(_stdcall* IDXGISwapChainPresentFn)(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
IDXGISwapChainPresentFn IDXGISwapChainPresent;

HRESULT __stdcall IDXGISwapChainPresentHook(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
auto ipc = IPC.Get<SettingsIPC*>();

static const double min_frame_delay = 1.0 / 10000.0; // just using 0 here causes roblox to freeze for some reason
*(double*)(TaskScheduler + TaskSchedulerFrameDelayOffset) = ipc->fps_cap <= 0.0 ? min_frame_delay : 1.0 / ipc->fps_cap;

ipc->debug.present_count++;

return IDXGISwapChainPresent(pSwapChain, ipc->vsync_enabled, Flags);
}

void CheckRunning()
{
char Name[64];
sprintf_s(Name, sizeof(Name), "RFUMutex_%d", GetCurrentProcessId());

SingletonMutex = CreateMutexA(NULL, FALSE, Name);

if (!SingletonMutex)
{
MessageBoxA(NULL, "Unable to create mutex", "Error", MB_OK);
DllExit();
}

if (GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBoxA(NULL, "Roblox FPS Unlocker is already running in this process", "Error", MB_OK);
DllExit();
}
}

extern "C"
{
__declspec(dllexport) void SetFPSCap(double cap)
{
SettingsIPC* fpscapper = new SettingsIPC({

});
fpscapper->fps_cap = cap;
MessageBoxA(NULL, "SetCap", "FrameR8", MB_OK);
}

__declspec(dllexport) void WINAPI Run()
{
MessageBoxA(NULL, "Running", "Test", MB_OK);
CheckRunning();

if (GetModuleHandleA("dxgi.dll"))
{
/* Init IPC */
IPC.Open("RFUSettingsMap", sizeof(SettingsIPC));
if (!IPC.IsOpen())
{
MessageBoxA(NULL, "Unable to initiate IPC", "Error", MB_OK);
DllExit();
}

/* Detect platform */
DetectPlatform();

/* Find TaskScheduler */
TaskScheduler = FindTaskScheduler();
if (!TaskScheduler)
{
MessageBoxA(NULL, "Unable to find TaskScheduler! This is probably due to a Roblox update-- watch the github for any patches or a fix.", "rbxfpsunlocker Error", MB_OK);
DllExit();
}

/* Find frame delay offset inside TaskScheduler */
TaskSchedulerFrameDelayOffset = FindTaskSchedulerFrameDelayOffset(TaskScheduler);
if (!TaskSchedulerFrameDelayOffset)
{
MessageBoxA(NULL, "Variable scan failed! This is probably due to a Roblox update-- watch the github for any patches or a fix.", "rbxfpsunlocker Error", MB_OK);
DllExit();
}

GetIPC()->debug.scheduler = (void*)TaskScheduler;
GetIPC()->debug.sfd_offset = TaskSchedulerFrameDelayOffset;
GetIPC()->debug.present_count = 0;

/* Create dummy ID3D11Device to grab its vftable */
ID3D11Device* Device = 0;
ID3D11DeviceContext* DeviceContext = 0;
IDXGISwapChain* SwapChain = 0;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC SwapChainDesc;

/* Create dummy window */
HWND DummyWindow = CreateWindowA("STATIC", "Dummy", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
if (!DummyWindow)
{
MessageBoxA(NULL, "Unable to create dummy window", "Error", MB_OK);
DllExit();
}

ZeroMemory(&SwapChainDesc, sizeof(SwapChainDesc));
SwapChainDesc.BufferCount = 1;
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.OutputWindow = DummyWindow;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.Windowed = TRUE;
SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

if (SUCCEEDED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_NULL, NULL, NULL, &FeatureLevel, 1, D3D11_SDK_VERSION, &SwapChainDesc, &SwapChain, &Device, NULL, &DeviceContext)))
{
/* Hook IDXGISwapChain::present & enable flag */
IDXGISwapChainPresent = (IDXGISwapChainPresentFn)HookVFT(SwapChain, 8, IDXGISwapChainPresentHook);

/* Free objects */
Device->Release();
DeviceContext->Release();
SwapChain->Release();
CloseHandle(DummyWindow);
}
else
{
MessageBoxA(NULL, "Unable to create D3D11 device", "Error", MB_OK);
DllExit();
}
}
}

}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
MainModule = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)DllInit, 0, 0, 0);
}

return TRUE;
}

void WINAPI DllInit()
{

}

void WINAPI DllExit()
{
if (SingletonMutex) CloseHandle(SingletonMutex);
FreeLibraryAndExitThread(MainModule, 0); // This probably doesn't free our module if we manually map /shrug
}[/CODE]
 
Argh my bad ... confusing DllInit and DllMain ...

You may want to move those functions (DllInit, DllMain, DllExit) into the extern "C" block and put __declspec(dllexport) at the beginning of those functions. I don't know if you need to put DllMain into the extern "C" block also. If you're not using the DllInit and DllExit functions elsewhere in the DLL you may want to comment out those function prototypes or at least get them to match the actual function signatures.

Interesting code ... I'll have to take some time to read and understand that ...
 
Hey Hey!
I had a quick look at your code last night as well as the screenshot, and noticed that you've mapped the exported function DllMain that's in the DLL to DllInit in your C# code. However, the DllMain function signature in the DLL does not match the DllInit function signature in your C# code. I'm guessing that you actually want to export the DllInit function from the DLL, and the screenshot is not showing that the DllInit function is being exported. You could use the example of how the SetFPSCap function is declared and apply that to the DllInit/DllExit functions (adding the __declspec(dllexport) stuff). What I find strange is that the Run function in the DLL export viewer contains a "_" at the beginning of the function name - I don't know why that would be. Also I don't know if it's a good idea to directly call the DllMain function.
One thing I noticed also was that the DllInit function was being called from the DllMain function, so it would seem that when the DLL gets loaded into memory by the program, the DllInit function will be called automatically (but that's something to test).
I had a quick look at the github repo that you posted a link to, and I'm guessing you're taking bits from there and making your own ... have you tried or is it possible to load the functions from the DLL that's created from the github repo?
I'll see if I can take a better look at things this weekend - it has been a busy week.
 
Hey Hey!
I had a quick look at your code last night as well as the screenshot, and noticed that you've mapped the exported function DllMain that's in the DLL to DllInit in your C# code. However, the DllMain function signature in the DLL does not match the DllInit function signature in your C# code. I'm guessing that you actually want to export the DllInit function from the DLL, and the screenshot is not showing that the DllInit function is being exported. You could use the example of how the SetFPSCap function is declared and apply that to the DllInit/DllExit functions (adding the __declspec(dllexport) stuff). What I find strange is that the Run function in the DLL export viewer contains a "_" at the beginning of the function name - I don't know why that would be. Also I don't know if it's a good idea to directly call the DllMain function.
One thing I noticed also was that the DllInit function was being called from the DllMain function, so it would seem that when the DLL gets loaded into memory by the program, the DllInit function will be called automatically (but that's something to test).
I had a quick look at the github repo that you posted a link to, and I'm guessing you're taking bits from there and making your own ... have you tried or is it possible to load the functions from the DLL that's created from the github repo?
I'll see if I can take a better look at things this weekend - it has been a busy week.
OH SO THE FUNCTION IS CALLED AUTOMATICALLY
 
That's DllMain, not DllInit right? https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain Take a read of the remarks section - it does describe loading DLLs in a Win32 context where LoadLibrary is used to load a DLL into the application's address space (but maybe that only applies when loading a DLL at runtime ... it might not be relevant if the DLL is managed at compile time ...)
Well regaurdless of what I put it still doesnt work, from DllMain to DllInit.
 
Howdy,
I've just created a sample solution in VS2019 community edition, which contains a DLL with exported functions as well as a couple of C++ console applications and a simple Windows Forms C# application. The C# application was targeting .NET 4 (not the more recent versions like 4.7.something). One thing I noticed was that the DLL needed to be compiled for x64 for the Windows Forms application to recognise the functions within the DLL. I'm going to do some cleanup of the solution and upload to GitHub so you can take a look and maybe get some ideas. Maybe it could be used as a tutorial like post elsewhere here, but maybe it'd be a bit advanced ... anyway, if there's any other feedback on it I'll take that into consideration.
 
Howdy,
I've just created a sample solution in VS2019 community edition, which contains a DLL with exported functions as well as a couple of C++ console applications and a simple Windows Forms C# application. The C# application was targeting .NET 4 (not the more recent versions like 4.7.something). One thing I noticed was that the DLL needed to be compiled for x64 for the Windows Forms application to recognise the functions within the DLL. I'm going to do some cleanup of the solution and upload to GitHub so you can take a look and maybe get some ideas. Maybe it could be used as a tutorial like post elsewhere here, but maybe it'd be a bit advanced ... anyway, if there's any other feedback on it I'll take that into consideration.
Thank you
 
Here 'tis: https://github.com/eeflores/DllTest
One thing I didn't consider when doing this was the possible expectation that I would be incorporating your code into the sample application, but I hope this will give you insight when trying to work with DLLs in general. I'm not sure if I have time to do the deep dive on what you currently have or are working on, but this has also been a learning experience for me, in just getting something done in VS2019. Maybe this week I can take some time to dissect the other parts of your code and that other GitHub project.
I'm sure you'll have questions, so fire away!
 
Here 'tis: https://github.com/eeflores/DllTest
One thing I didn't consider when doing this was the possible expectation that I would be incorporating your code into the sample application, but I hope this will give you insight when trying to work with DLLs in general. I'm not sure if I have time to do the deep dive on what you currently have or are working on, but this has also been a learning experience for me, in just getting something done in VS2019. Maybe this week I can take some time to dissect the other parts of your code and that other GitHub project.
I'm sure you'll have questions, so fire away!
Well first off I just want to say thank you so much for taking this time off of what you would normally do. And second ill compare my code with yours and see what happens when I use yours vs the other one.

Also what is that #cplusplus thing about?
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom