Converting an OpenGl rendeing project into dll

Hello

i have implemented a rendering tool with opengl ( 32 bit - Release - C++ - console application ) which can be called in the main function by calling a class which contains just one method with 5 arguments .

point 1 : In this class called ( Run_Class ) several other classes inside the project are called and instantiated . ( Run_class contains what ever that was before inside the main function -i just made it into a class with one method.

point 2 : basically , what the program does , is to call opengl functions , open a window , load a model , take some snapshots , and give the user back the snapshots in BYTE .

Now :
-----
I want to convert this project into a dll to be used like a tool in .net core .
i have searched a lot and i faced 2 solutions :
#1 P/invoke
#2 c++/cli
------
since my c++ project contains 10 classes and at the end just one method to be called , i chose the p/invoke method .
------
but i can't find a blue print to help me understand how to make this work.

- how to convert the already existing c++ project into a dll
- how to do the dll so it can be called later by .net core
- How to call this method from the mnetioned dll from .net core

Tnx
Last edited on
You do it like this:
1. Under project properties, in General > Configuration Type, select Dynamic Library. This tells the toolchain to link a DLL rather than an executable.
2. Delete main() from the code.
3. Add these functions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define API extern "C" __declspec(dllexport)

API Run_Class *mylib_create_Run_Class(){
    try{
        return new Run_Class;
    }catch (std::exception &){
        return nullptr;
    }
}

API void mylib_destroy_Run_Class(Run_Class *rc){
    delete rc;
}

API void mylib_Run_Class_do_it(Run_Class *rc){
    rc->do_it();
}
Add any other functions you need following the same pattern.

The above creates a DLL with a C ABI. Such DLLs can be called directly by .NET programs using P/Invoke. You can search for P/Invoke examples online.
hello

Thanks for your reply

i made a dll out of the project and now i want o to make it work from a c# application.

- the dll is made in X86 - Relase mode
- the dll has a lot od dependencies on other dlls that were additionally added to the project .
( with out the linking the dlls into my project , the code inside the dll could not get built )
- now from the C# side , i get the following error :

C# - console app - X86 - debug - .net core console application

System.DllNotFoundException: 'Unable to load DLL 'C:\Users\pouya\Documents\Visual Studio 2019\Projects\Progect_c\Release\test_DLL.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)'


where does the problem be from ?
Did you put the DLL next to the executable? The runtime will only look in a few places for the DLL before giving up.
hello

this is the way i built my dll , i don't know if it is right ot not , i could not figure out how to make your solution work .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\RUNCLASS.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\RUNCLASS.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Libs.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Shader.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Shader.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Camera.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Camera.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Model.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Model.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Texture.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Texture.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Window.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Window.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Light.h"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Light.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Mesh.cpp"
#include "C:\Users\pouya\source\repos\Clonident\Project_Theis\Mesh.cpp"

//C:\Users\pouya\source\repos\Clonident\Project_Theis

extern "C" __declspec(dllexport) void Take_snapShot(const void* pbuffer, size_t plenght, std::vector<float> angoli, std::string output_path, float Increase_scale, bool _x_axis, bool _Y_axis, bool _Z_axis)
{

    RUNCLASS RC(pbuffer, plenght, angoli, output_path, Increase_scale, _x_axis, _Y_axis, _Z_axis);
    RC.snapshot_wih_loop_in_memory_output_path();
}



plus , as i mentioned , the opengl c++ app , utilizes external dlls itself , i just add those dependencies the same way to the dll project , in properities/ c/c++ and linker

-----------------
on the c# side :

1
2
3
4
5
6
7
8
9
10
11
12
        [DllImport("C:\\Users\\pouya\\source\\repos\\Clonident\\Release\\Clonident_DLL.dll")]

        public static extern void Take_snapShot(System.String pbuffer, System.UInt32 plenght, Array angoli, string output_path, float Increase_scale, bool _x_axis, bool _Y_axis, bool _Z_axis);

 string filePath = @"C:\Users\pouya\source\repos\Clonident\Project_Theis\Models\MaxillaryPreScan.stl";

            byte[] my_file = File.ReadAllBytes(filePath);
            // list 
            float[] lst_num = new float[5] { 10, 40, 200, 800, 890 };


            Take_snapShot(Encoding.Default.GetString(my_file), (uint)my_file.Length, lst_num, "_dll_tst.jpg", 10, true, true, true);


--------------------
- the dll file of the project is placed in the Release folder of the project.
- i don't know if the dependencies should also be in Relase folder or not ( they are headers and .lib files )
- the opengl uses opengl in linker as an external library ( plus a bunch of other dlls ) , the dll also need to make use of them .
- i have iimplemented a simple math operation using this approach and it workd , agian , your solution seems hard to me since i don't understand it
- please provide the name of your approach , what should i search on the net to find a more detailed solution
Thanks
Last edited on
update :

i tried to implement your solution as the following :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define API extern "C" __declspec(dllexport)

API RUNCLASS* mylib_create_RUNCLASS() 
{
	try
	{
		return new RUNCLASS();
	}
	catch (const std::exception&)
	{

	}
}
API void mylib_create_RUNCLASS(RUNCLASS* rc) {
	delete rc;
}

API void mylib_create_RUNCLASS(RUNCLASS* rc) {
	rc->snapshot_wih_loop_in_memory_output_path();
}



and i get this error while building the dll :

Severity Code Description Project File Line Suppression State
Error C2733 'mylib_create_RUNCLASS': you cannot overload a function with 'extern "C"' linkage Project_Theis C:\Users\pouya\source\repos\Clonident\Project_Theis\Project_Theis.cpp 22

i tried to add the externall libs that the opengl itself needs for the project into the release folder ( which the execution file exist ) , and now i get another exception error in .net which tells me about an exception in the dll itself .

can it be becasue of the wrong marshalling of the data while using the p/invoke mechanism ?
can it be becasue of the wrong marshalling of the data while using the p/invoke mechanism ?
Well, yeah. Most definitely. Just as an example, you're telling C# the external function expects a System.String on the fourth parameter and the actual implementation takes an std::string on that parameter. Why would you expect that to work, when C# doesn't understand C++ types and C++ doesn't understand C# types?
Registered users can post here. Sign in or register to post.