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

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
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:
#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 *>();
}

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:

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
I've seen something along these lines: https://stackoverflow.com/a/15773851 where you have a DLL where the functions are mapped to class functions via annotations.
I'll have to take a look at this later: this is probably related to your other question https://codeforum.org/threads/same-code-issue.494/
That would be in c# im looking in c++,
Example:
C++:
MessageBoxA(NULL, "Unknown platform", "Error", MB_OK);
That would be how to make a message box in c++, how would i call that function with c#? (Its just an example ik how to make a messagebox in c#).
 

eeflores

Coder
Jun 26, 2019
58
17
8
From Stackoverflow:

Code:
You may need to use DllImport

[DllImport(@"C:\Cadence\SPB_16.5\tools\bin\mpsc.dll")]
static extern void mpscExit();
where mpscExit() is a function in the DLL, and this declaration is within the C# code.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
From Stackoverflow:

You may need to use DllImport
[DllImport(@"C:\Cadence\SPB_16.5\tools\bin\mpsc.dll")]
static extern void mpscExit();

where mpscExit() is a function in the DLL, and this declaration is within the C# code.
I have done that. I get an error within. I edited the first post, please take a look at that.
 

eeflores

Coder
Jun 26, 2019
58
17
8
I'll have to find or come up with an example, but I can't do that right now.

... Ah! I have an example of that ... there's a certain way you have to export external functions from a DLL ... there's 2 ways: via another file that defines the exported functions from a DLL, and there should be a way to do it from the C code ... I should be able to find that soon.

Aha! I had some code ... maybe you could look this up (this is probably an old way of doing things, but maybe still relevant):

Code:
__declspec(dllexport) void someFunc(int param1)
{
}
I'm not sure if the WINAPI macro does something similar or if there's a similar macro for exporting functions. There's also another way where you declare exported functions in another file but then you'd have to modify the compilation parameters to use that file.

oh, and the other thing you may want to do is surround your exported functions (if you're using C++) in "extern "C"" braces:

Code:
extern "C"
{
// exported functions go here
}
This should get around any name mangling that C++ does.

You can also confirm what functions are exported from a DLL via a tool: https://www.nirsoft.net/utils/dll_export_viewer.html but I think there's also either a Windows option (file information or something like that, or command line tool) or it may also be possible via tools provided via Visual Studio.
 

eeflores

Coder
Jun 26, 2019
58
17
8
My function doesnt have any parameters.
That's fine, but it is possible to export functions that take parameters. You just have to be mindful of converting parameters you pass to the function - types that are passed in. Basic types should probably be fine, but things get hairy when you're passing in structs I think.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
That's fine, but it is possible to export functions that take parameters. You just have to be mindful of converting parameters you pass to the function - types that are passed in. Basic types should probably be fine, but things get hairy when you're passing in structs I think.
Alrighty!
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
I see the exported functions in the function viewer, thank you very much! I am going to try this in c#.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
You can also confirm what functions are exported from a DLL via a tool: https://www.nirsoft.net/utils/dll_export_viewer.html but I think there's also either a Windows option (file information or something like that, or command line tool) or it may also be possible via tools provided via Visual Studio.
So it did work but with one issue, "
An unhandled exception of type 'System.EntryPointNotFoundException' occurred in FPS Counter.exe
Unable to find an entry point named 'DllInit' in DLL 'rbxfpsunlocker.dll'.
"

Then a messagebox shows up "Unable to initiate IPC".

But that message box is in the code.
 

eeflores

Coder
Jun 26, 2019
58
17
8
An unhandled exception of type 'System.EntryPointNotFoundException' occurred in FPS Counter.exe
Unable to find an entry point named 'DllInit' in DLL 'rbxfpsunlocker.dll'.
It looks like you have the function declaration in your code, but not those actual functions (DllInit, DllExit). You could try just commenting out those for now. DllInit is usually called when the DLL is loaded into memory so that it can do some initialisation, but it shouldn't be necessary.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
It looks like you have the function declaration in your code, but not those actual functions (DllInit, DllExit). You could try just commenting out those for now. DllInit is usually called when the DLL is loaded into memory so that it can do some initialization, but it shouldn't be necessary.
But that is the code I need to call.
 

eeflores

Coder
Jun 26, 2019
58
17
8
But that is the code I need to call.
It should be enough to declare an empty function so that stuff works. You currently have a function prototype for DllInit and DllExit but not the actual function. You may want to confirm this with that DLL tool that I mentioned earlier.

Speaking of DllInit, it's one of those special functions that Windows relies on or uses, like WinMain. It has a specific function signature and is used by Windows in a certain way: https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain . You may want to use a different function name for yourself, but maybe the Microsoft version is what you really want.

@Malcolm there's a bit of hokey pokey black magic when it comes to loading and calling functions that exist in a DLL as opposed to functions being compiled into the same application. Usually in a project you can specify that the DLL exists and as long as you have a definition of the functions you can perform a compile-time linking to the DLL. It's also possible to dynamically load a DLL into an application so you could change out the DLL for an updated version without needing to recompile the executable. For some light reading: https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking

An interesting side note (and probably something along the lines of what @TableFlipGod is trying to do) some "hacks" to fix or get older versions of applications to work is by substituting in a DLL that hacks or fixes the problems in the application. dsfix (https://github.com/PeterTh/dsfix) comes to mind, but I think I remember seeing hacks to get Diablo and Starcraft to work on modern PCs by using this method. A replacement/shim DirectX DLL would be put into the same folder as the application and would intercept function calls intended for the system DirectX layer, but these would typically translate old/deprecated/obsolete function calls to their newer counterpart.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
An interesting side note (and probably something along the lines of what @TableFlipGod is trying to do) some "hacks" to fix or get older versions of applications to work is by substituting in a DLL that hacks or fixes the problems in the application. dsfix (https://github.com/PeterTh/dsfix) comes to mind, but I think I remember seeing hacks to get Diablo and Starcraft to work on modern PCs by using this method. A replacement/shim DirectX DLL would be put into the same folder as the application and would intercept function calls intended for the system DirectX layer, but these would typically translate old/deprecated/obsolete function calls to their newer counterpart.
So I should try that?
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
It should be enough to declare an empty function so that stuff works. You currently have a function prototype for DllInit and DllExit but not the actual function. You may want to confirm this with that DLL tool that I mentioned earlier.

Speaking of DllInit, it's one of those special functions that Windows relies on or uses, like WinMain. It has a specific function signature and is used by Windows in a certain way: https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain . You may want to use a different function name for yourself, but maybe the Microsoft version is what you really want.
I used that tool to confirm it is a public function. It does run code because the message box shows up from the c++ function.
 

TableFlipGod

Active Coder
May 13, 2019
121
25
29
14
I
@Malcolm there's a bit of hokey pokey black magic when it comes to loading and calling functions that exist in a DLL as opposed to functions being compiled into the same application. Usually in a project you can specify that the DLL exists and as long as you have a definition of the functions you can perform a compile-time linking to the DLL. It's also possible to dynamically load a DLL into an application so you could change out the DLL for an updated version without needing to recompile the executable. For some light reading: https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking
I also took a look at that and it didn’t help my case
 

eeflores

Coder
Jun 26, 2019
58
17
8
So I should try that?
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.
used that tool to confirm it is a public function. It does run code because the message box shows up from the c++ function.
Do you have empty functions for DllInit and DllExit?