DLLBind is currently not working



  • Finally I tested it out, writting my own DLL and porting a SHA256 C Library.
    Unfortunately, the compiler doesn’t recognize the DLLBind and dllimport keywords, and throws an error right away.
    The documentation says DLLBind is disabled by default on fully licensed projects, like Chivalry. However, DLLBind is our only hope of hooking external libraries into the game.
    Without DLLBind, implementing similar concepts will not only be slower but take a huge amount of time, most likely not worth the trouble.
    Any chance of enabling it on your side?

    Here is the Unreal Script code I’ve written:

    class TestBind extends AOCFFA
       DLLBind(TestBind);
    
    protected dllimport final function int GetHashSize();
    protected dllimport final function int GetHashHexSize();
    protected dllimport final function bool IsHashed(array <byte>Hash);
    protected dllimport final function bool SHA256Hash(array <byte>Content, out array <byte>Hash);
    
    function string HashToHex(array <byte>Hash)
    {
    
        local string HashString;
        local int i;
        local int short;
    
        if (Hash.Length != GetHashSize())
            return "";
    
        HashString = "0x";
    
        for (i = 0; i < Hash.Length; i += 2)
        {
    
            short = ((int(Hash[i]) << 8) | int(Hash[i+1]));
            HashString $= ToHex(short);
    
        }
    
        return (((Len(HashString) - 2) == GetHashHexSize()) ? HashString : "");
    
    }
    
    function GetHash(coerce string s)
    {
    
        local int i, c;
        local array <byte>ByteString;
        local array <byte>Hash;
    
        if (s == "")
            return;
    
        for (i = 0; i < Len(s); i++)
        {
    
            c = Asc(Mid(s, i, 1));
    
            if (c > 255)
            {
    
                ByteString.AddItem(((c >> 8) & 0xFF));
                ByteString.AddItem((c & 0xFF));
    
            }
    
            else
                ByteString.AddItem(c);
    
        }
    
        Hash.Add(GetHashSize());
    
        if (!SHA256Hash(ByteString, Hash))
            return;
    
        `LogAlways("--- HASH:"@HashToHex(Hash));
    
    }
    
    Auto State AOCPreRound
    {
    
        function BeginState(Name PreviousStateName)
        {
    
            GetHash("Hello World");
    
            super.BeginState(PreviousStateName);
    
        }
    
    }[/i]</byte></byte></byte></byte></byte></byte>
    


  • I’ll have to test this, but if it’s true that DLLBind is disabled - that cripples a lot of interesting concepts as Cthulhu suggests. Please TBS enable this, it would be a huge boon to the modding community!



  • For those interested in an update:

    I spoke with CrustaceanSoup and Markus, they’ve agreed to activate DLLBind for the next major SDK update :). Great news all around, thanks a lot TBS!



  • If you want to chat in real-time with your fellow Chivalry modders, and possibly some devs, join us in #tornbanner on QuakeNet (webchat). I still recommend posting questions in this forum though; we don’t respond on IRC immediately – most of the team doesn’t check it at all – and posting to this forum means others can read answers.

    Why is this the opposite?
    Most of my threads in here go unnoticed by the devs.

    As for DLLBind, you must make extra sure that DLLBind won’t be causing VAC bans.
    After all, UDK will be dynamically loading a non-official DLL.

    It doesn’t really cripples development, DLLBind is very limited by itself.
    However, certain things are better done in a language that is fast enough and already has a fair share of libraries that aren’t in Unreal Script.
    You shouldn’t be using DLLBind to replace stuff within Unreal Script. In fact, you should avoid DLLBind like the devil and only use it when it’s the most logical approach to your problem, AKA, wrappers for C/C++ libraries.

    I’ve a significant amount of work done in the SDK by now, and these are the only functions that I needed DLLBind for:

    extern "C"
    {
    
        __declspec(dllimport) int __stdcall GetHashSize();
        __declspec(dllimport) int __stdcall GetHashHexSize();
        __declspec(dllimport) bool __stdcall IsArrayZeroed(struct TArray <unsigned char="">*ByteArray);
        __declspec(dllimport) bool __stdcall StringToBytes(wchar_t *s, struct TArray <unsigned char="">*ByteArray);
        __declspec(dllimport) int __stdcall GetStringToBytesSize(wchar_t *s);
        __declspec(dllimport) wchar_t __stdcall *BytesToHex(struct TArray <unsigned char="">*ByteArray, int Precision);
        __declspec(dllimport) bool __stdcall SHA256Hash(struct TArray <unsigned char="">*ByteArray, struct TArray <unsigned char="">*Hash);
        __declspec(dllimport) bool __stdcall SHA256StringHash(wchar_t *s, struct TArray <unsigned char="">*Hash);
    
    }</unsigned></unsigned></unsigned></unsigned></unsigned></unsigned>
    


  • It doesn’t really cripples development, DLLBind is very limited by itself.
    However, certain things are better done in a language that is fast enough and already has a fair share of libraries that aren’t in Unreal Script.

    Depends what you’re trying to do, Cthulhu. From what I can tell, you’re mostly using DLLBind to have access to utility functions. In my case, I’m trying to ensure database persistence via MySQL or SQLite - which is very challenging without DLLBind.

    As far as I’m concerned, the greatest value of DLLBind is to ensure server-side communication with services which can enable a new dimension to the modding and gaming experience. Not having DLLBind would definitely cripple that effort.

    You shouldn’t be using DLLBind to replace stuff within Unreal Script. In fact, you should avoid DLLBind like the devil and only use it when it’s the most logical approach to your problem, AKA, wrappers for C/C++ libraries.

    I’m not sure why you would assume that, there are many more far more interesting use-cases for DLLBind than replacing existing UnrealScript functionality.

    As for DLLBind, you must make extra sure that DLLBind won’t be causing VAC bans.
    After all, UDK will be dynamically loading a non-official DLL.

    I’m pretty sure that DLLBind is whitelisted since its loaded in the context of a packaged mod which the server also loads and expects/requests. Still, good point, worth a look.



  • @Nightrise:

    Depends what you’re trying to do, Cthulhu. From what I can tell, you’re mostly using DLLBind to have access to utility functions. In my case, I’m trying to ensure database persistence via MySQL or SQLite - which is very challenging without DLLBind.

    Not really. You can use either TcpLink or UdpLink to contact a middleman application to write/read your database.
    Not too long ago, I did this same concept to communicate a WSGI application with another server running a MySQL database. Both WSGI and Query Server were written in Python, which made development much faster and easier to debug.
    Not only is this a safer way to implement it, but also likely to perform much better.

    @Nightrise:

    As far as I’m concerned, the greatest value of DLLBind is to ensure server-side communication with services which can enable a new dimension to the modding and gaming experience. Not having DLLBind would definitely cripple that effort.

    That falls into TcpLink and UdpLink, rather than DLLBind.
    A class is only allowed to DLLBind a single DLL, which pretty much limits extensive use of it.
    You can also not access Unreal Script methods and other members from the DLL, so meh.

    @Nightrise:

    I’m not sure why you would assume that, there are many more far more interesting use-cases for DLLBind than replacing existing UnrealScript functionality.

    I said you shouldn’t use DLLBind to replace Unreal Script, not that you can’t use it for anything else.

    @Nightrise:

    I’m pretty sure that DLLBind is whitelisted since its loaded in the context of a packaged mod which the server also loads and expects/requests. Still, good point, worth a look.

    The way DLLBind loads its DLL is fairly close to how you inject a DLL into a running process.
    It also unloads when the object is garbage collected, which could trigger false positives within VAC.



  • Not really. You can use either TcpLink or UdpLink to contact a middleman application to write/read your database.
    Not too long ago, I did this same concept to communicate a WSGI application with another server running a MySQL database. Both WSGI and Query Server were written in Python, which made development much faster and easier to debug.
    Not only is this a safer way to implement it, but also likely to perform much better.

    I definitely agree that TcpLink can be great for communicating with web services, and I have no doubt you could do it this way (at least as far as databases are concerned). However, I’d have to disagree if you’re making the claim that it’s easier or performs better. Calling a native dll function to write to MySQL, for instance, is likely faster and more time-efficient (coding-wise) than establishing a TCP link via a middle-man application, like a web application, (which is additional overhead), which then in turn writes to the database (especially if its written in something like python).

    Ultimately, communicating with a local service will be better accomplished, and a lot more reliable via DLLBind, especially given the reality that are many highly optimized libraries designed for UnrealScript to communicate with various services. (See here for MySQL + SQLite DLL for UnrealScript)

    That falls into TcpLink and UdpLink, rather than DLLBind.
    A class is only allowed to DLLBind a single DLL, which pretty much limits extensive use of it.
    You can also not access Unreal Script methods and other members from the DLL, so meh.

    Again, I’m not sure what use-case you have in mind, but I have yet to encounter a situation where that matters much. In the context of communicating with a service, I have never had to bind more than one DLL to a given class, nor do I see why you’d want to use Unreal Script methods inside the DLL. Discrete interactions for data processing, retrieval, and/or insertion are what I’m interested in personally.

    Regardless, the point of this thread isn’t to discuss implementation details or design choices, but rather to enable a powerful feature which, I’m sure, creative modders will likely appreciate. Beyond that, whether you choose to use it or not is entirely up to you at the end of the day, but at least you’ll have the option.



  • Except that UDK is single threaded. It doesn’t matter how you implement your DLL, since it will be called within UDK you will not be able to take advantage of multi-processing.
    The more stuff you put into UDK, the more you risk wasting essential CPU time with trivial stuff that could’ve been performed elsewhere.
    Chivalry is already pretty bad when it comes to optimization, do you really want to make it worse?

    It’s also significantly easier than writting a DLL. Almost all of it’s features will be actually done on your Python end, which is a very high level language with lots of modules.
    All this -> http://forums.epicgames.com/threads/726 … Lite-MySQL-v3-1-0-2 can be written in a single file for Python.

    Besides, you do realize that you still need to connect to your database right?
    All this should be done locally, server -> middleman -> database, instead of, server -> database.
    Sending raw, non-formatted data to the middleman application (which is likely to be faster than SQL) can alleviate overhead in the server application, therefore, in a multi-processor machine, it will actually perform better.

    Games like RO2 don’t have DLLBind enabled and modders in there haven’t committed suicide yet.
    I’m not saying I don’t want it, after all, I’m the one who just made this thread, I’m just saying that modding without DLLBind is completely possible.
    Also, another reason to avoid DLLBind whenever you can is code manageability, if you want people to be able to easily port/implement your mod.


  • Developer

    I do think there are instances where DLLBind could be useful. Obviously it’s also possible to use it to turn your project into a giant mess.

    We’ve looked over the DLLBind-related code and it doesn’t appear as though enabling it could cause any issues with existing, non-DLLBind classes. We’re not going to allow for distribution of DLLs through the Workshop, mind you, but I’m sure that won’t be a huge deal if it’s mostly used for servers.



  • After the last update, DLLBind compiles but doesn’t work.

    #include <windows.h>
    
    extern "C"
    {
    
        __declspec(dllexport) int __stdcall Test1()
        {
    
            return 55;
    
        }
    
        __declspec(dllexport) int __stdcall Test2()
        {
    
            int i = 105;
    
            return i;
    
        }
    
    }</windows.h>
    

    Compiled with:

    g++ -static-libgcc -static-libstdc++ -O2 -Wall -Wextra -o MyDLL.dll -s -shared MyDLL.cpp -Wl,--subsystem,windows
    

    MyDLL placed at Binaries/Win32/Usercode.

    class TestBind extends AOCFFA
        DLLBind(MyDLL);
    
    dllimport final function int Test1();
    dllimport final function int Test2();
    
    event InitGame(string Options, out string Error)
    {
    
        `LogAlways("-- Test1:"@Test1());
        `LogAlways("-- Test2:"@Test2());
    
        super.InitGame(Options, Error);
    
    }
    

    Output:

    [0012.93] ScriptLog: -- Test1: 0
    [0012.93] ScriptLog: -- Test2: 0
    

    Importing the DLL into another C++ application works just fine.



  • Was DLLBind disabled again? The SDK compiler doesn’t seem to accept it.


Log in to reply