Announcement

Collapse
No announcement yet.

[WIKI] Creating and Linking Dlls -- Reloaded

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [WIKI] Creating and Linking Dlls -- Reloaded

    Hello,

    I read this wiki article Linking Dlls but sadly it is very incomplete, outdated and a little bit chaotic.
    I'd like to update the article and improve it to be more beginner friendly.. but:

    My problem is that I need the exact code in the .h and .cpp files of the DLL ( for VS 2015 ). The Unreal part seems to work but the .dll method doesn't return a thing.. not even an exception.

    Could someone please tell me the exact .h and .cpp code ?
    Or do you have any simple example I can look at to understand the general syntax of DLLs ?


    Best
    GreetinGs

    #2
    Hi XenoEgger,

    Hhahaha, I made that wiki loooooong time ago, let me help you a little bit, start by creating an empty c++ project Win32 Console Command, choose DLL and empty Project

    like this:
    Click image for larger version

Name:	DLL.jpg
Views:	1
Size:	130.1 KB
ID:	1118532

    this is my H:

    Code:
    #ifndef __MAIN_H__
    #define __MAIN_H__
    #pragma once
    #include <windows.h>
    /*  To use this exported function of dll, include this header
    *  in your project.
    */
    #define DLL_EXPORT __declspec(dllexport)
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    	float DLL_EXPORT getCircleArea(float radius);
    #ifdef __cplusplus
    }
    #endif
    #endif // __MAIN_H__
    and the cpp:
    Code:
    #pragma once
    #include "main.h"
    
    // a sample exported function
    float DLL_EXPORT getCircleArea(float radius)
    {
    	return 3.1416f * (radius * radius);
    }
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    	switch (fdwReason)
    	{
    	case DLL_PROCESS_ATTACH:
    		// attach to process
    		// return FALSE to fail DLL load
    		break;
    	case DLL_PROCESS_DETACH:
    		// detach from process
    		break;
    	case DLL_THREAD_ATTACH:
    		// attach to thread
    		break;
    	case DLL_THREAD_DETACH:
    		// detach from thread
    		break;
    	}
    	return TRUE; // successful
    }
    following the same example provided
    BTW there is a lot of info about how to create DLLs for c++ or c#, see examples from web

    Cheers

    Comment


      #3
      Thank you very much! Now it works!

      I tried and read a whole day before I asked the question here. So I just didn't get it done without your help.
      I'll update the wiki article this weekend++ and add more details, like loading the .dll at the start only once and how to wrap the .dll in an Unreal Engine plugin the next months.

      So.. what is the method DllMain good for ?
      Last edited by Jokerminator; 11-20-2016, 01:21 PM. Reason: need more time

      Comment


        #4
        DLLmain is just some extra options for your dll, not needed but good practice
        And thanks for update the wiki, you can add how to deal with DLLs inside plugins for example, or tell me when you done with it, and then I will add how to compile and package dll from plugins

        Comment


          #5
          I added some more code to the existing example of the wiki article Linking Dlls. The bool, int and float returning methods always work but I have some trouble with the method that returns a string.
          The Editor seems to crash randomly. 50% of the time it works. The other 50% it doesn't work. The Editor crashes with this error message:

          Access violation - code c0000005 (first/second chance not available)

          UE4Editor_Core
          UE4Editor_Core
          UE4Editor_Core
          UE4Editor_Core
          UE4Editor_CreateAndLinkDLLProj!operator delete() [e:\2016\createandlinkdllproj\source\createandlinkdllproj\createandlinkdllproj.cpp:5]
          UE4Editor_CreateAndLinkDLLProj!UCreateAndLinkDLLTutBFL::getAdditionalStringFromDll() [e:\2016\createandlinkdllproj\source\createandlinkdllproj\private\createandlinkdlltutbfl.cpp:81]
          UE4Editor_CreateAndLinkDLLProj!UCreateAndLinkDLLTutBFL::execgetAdditionalStringFromDll() [e:\2016\createandlinkdllproj\source\createandlinkdllproj\public\createandlinkdlltutbfl.h:11]
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_CoreUObject
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_Engine
          UE4Editor_UnrealEd
          UE4Editor_UnrealEd
          UE4Editor_UnrealEd
          UE4Editor_UnrealEd
          UE4Editor_UnrealEd
          UE4Editor
          UE4Editor
          UE4Editor
          UE4Editor
          UE4Editor
          kernel32
          ntdll


          The project source ( 4.13.2 ) can be downloaded here: Project Source Code
          You probably need to rebuild the DLL and copy it to the Plugins folder. I use a 64-bit Windows 10.

          What am I doing wrong ?
          Using char instead of string would also fine with me.

          ( In the meantime I'll add some methods for int and bool.. -> Done! )
          Last edited by Jokerminator; 11-25-2016, 03:09 PM.

          Comment


            #6
            HI XenoEgger,

            Good work, by updated wiki, additionally you don't need track you dll position in certain folder, if you put your dll inside plugin's binary folder (Win64 for example) it must be work just calling the name like this: FPlatformProcess::GetDllHandle("mydll.dll");, also you can package your dll directly to your package game, using this on your build.cs: RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(BinaryMasterPath, "mydll.dll")));

            finally for some reason UE hate c++ stl, instead use string.h try using char* you can easily parse your char* to FString of viceversa by using: TCHAR_TO_ANSI(*happyFString) or ANSI_TO_TCHAR(happyCharPtr);

            Comment


              #7
              Hey ZkarmaKun,

              Thank you for your answer and tips.

              I tried to find a way to get the DLL to work with char* but sadly I had no luck. I am new to pointers ( I am a C# programmer ) so I have no clue how to send the char array to the DLL and get an other array back.

              Do you have a hint for me ?


              Best
              Greetings

              Comment


                #8
                Hi XenoEgger,

                In case Char(s) values, one Char* work usually like and array, lets say: Char myChar = 's', is just 1 char inside that variable, but in case of Char* ptrChar = "hello!", could work as array, because remember 1 string is just 1 char array, and like I said, could be, because some times, a Char* could be just bytes, or something else, in image processing for example we used store image data inside Char* as bytes chains,

                Try this on your dll code:
                Code:
                .h
                char DLL_EXPORT *getCharArray();
                
                .cpp
                char DLL_EXPORT *getCharArray()
                {
                     char* var = "hello";
                     return var;
                }

                Comment


                  #9
                  Hey ZkarmaKun,

                  Thank you again! I have added some parameter to the method as well and it works just fine.

                  I'm still not sure why it is *getCharArray() and not just getCharArray() without the pointer thingy.. but.. as long as it works I am happy.

                  One last question: How do I send / receive a struct like a Vector3 or a Quaternion ?


                  Best
                  Greetings

                  Comment


                    #10
                    Hi XenoEgger,

                    you might export your struct or even classes in the same way:
                    Code:
                    struct DLL_EXPORT FVector
                    {
                    float X;
                    float Y;
                    float Z;
                    
                    };
                    
                    FVector DLL_EXPORT getVector();
                    
                    .cpp
                    FVector DLL_EXPORT getVector()
                    {
                    return FVector();
                    
                    }
                    Noticed I am using the same name for my dll declaration, this act like forward declarations in between UE and the DLL, which is a similar implementation for UE plugins modules, either way try to avoid DLL for that, DLL are useful for hard connections between programs, but we are using c++ in UE and almost everything is possible, have fun

                    Comment


                      #11
                      Hi ZkarmaKun,

                      Thank you for the warning.

                      I have added a send / receive vector 4 from / to DLL method that works basically the same way like I did it for the char.

                      Would I also need to free some memory ( of the functions/methods and variables ) after I used these pointers ? ( I read function pointers don't need to be de-/allocated.. but I dunno. )


                      Best
                      Greetings

                      Comment

                      Working...
                      X