Repository: godot
Issue: Can't open dynamic library
Labels: topic:gdextension

### Godot version

3.4.4.stable

### System information

Windows 10 Pro x64, Intel I7-9750H x64, 16GB RAM, NVIDIA GeForce GTX 1650, Driver Version 30.0.15.1179, Backend GLES3

### Issue description

I'm trying to link PostgreSQL to Godot thru GDNative using [libpqxx](https://github.com/jtv/libpqxx), after i link all the necessary files and the windows socket in the scons file it generates a .dll file, but every time i try to instantiate the GDNative class it crashes and throws the error "Attempting to call function 'new' in base 'NativeScript' on a null instance".

I also get this message in the cmd:
```
ERROR: Can't open dynamic library: C:/Users/Avell/Projetos de Jogos/Godot Projects/gdnative_cpp_example/demo/bin/win64/libgdexample.dll, error: Error 126: Couldn't find the specified module.
.
   at: (platform/windows/os_windows.cpp:2353)
ERROR: No valid library handle, can't get symbol from GDNative object
   at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No nativescript_init in "res://bin/win64/libgdexample.dll" found
   at: init_library (modules/gdnative/nativescript/nativescript.cpp:1510)
ERROR: Condition "!script_data" is true.
```

### Steps to reproduce

I'm using this [GDNative example project](https://github.com/BastiaanOlij/gdnative_cpp_example) and the regular [godot cpp repo](https://github.com/godotengine/godot-cpp), cloned the godot-cpp repo using --recursive -b 3.x thru git bash and built it with:
```scons generate_bindings=yes platform=windows target=release bits=64```

After that i draged it into the GDNative example directory ending up with something like this:

![image](https://user-images.githubusercontent.com/32317045/170593661-9daa832b-4493-45bb-8efc-2ea9a0271c37.png)

Then i've downloaded and installed [PostgreSQL Version 12.11 for Windows x86_64](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads) 

After that i cloned the [libpqxx](https://github.com/jtv/libpqxx) repo inside of my GDNative directory, ending up with something like this:

![image](https://user-images.githubusercontent.com/32317045/170594213-1774e716-8a60-4dc3-aaff-0deec221885c.png)

Then i've built it following [this tutorial](https://www.youtube.com/watch?v=qDiC1Wja6Og&ab_channel=Instituteofmarxism-leninism) 'till the minute 10:20, the only difference being that in the Visual Studio 2019 interface i got the C++ version to standard C++17 and not latest in both the files he built.

After that i've linked the necessary paths to the SConstruct file. Here's the code:

```Python
# make sure our binding library is properly includes
env.Append(CPPPATH=[
    '.',
    godot_headers_path,
    cpp_bindings_path + 'include/',
    cpp_bindings_path + 'include/core/',
    cpp_bindings_path + 'include/gen/',
    "C:/Program Files (x86)/Windows Kits/10/Include/10.0.22000.0/",
    "C:/Program Files/PostgreSQL/12/include/",
    "C:/Program Files/libpqxx/include/",
    ]
)
env.Append(LIBPATH=[
    cpp_bindings_path + 'bin/',
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22000.0/um/x64/',
    'C:/Program Files/PostgreSQL/12/lib/',
    'C:/Program Files/libpqxx/lib',
    ]
)
env.Append(LIBS=[
    cpp_library,
    "WS2_32",
    "libpq",
    "pqxx",
    ]
)

# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=['src/'])
sources = Glob('src/*.cpp')

library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)

Default(library)

# Generates help for the -h scons option.
Help(opts.GenerateHelpText(env))
```

After that i've added ```/std:c++17``` as a CCFLAG as in the following code:

```Python
elif env['platform'] == "windows":
    env['target_path'] += 'win64/'
    cpp_library += '.windows'
    # This makes sure to keep the session environment variables on windows,
    # that way you can run scons in a vs 2017 prompt and it will find all the required tools
    env.Append(ENV = os.environ)

    env.Append(CCFLAGS = ['-DWIN32', '-D_WIN32', '-D_WINDOWS', '-W3', '-GR', '-D_CRT_SECURE_NO_WARNINGS'])
    if env['target'] in ('debug', 'd'):
        env.Append(CCFLAGS = ['-EHsc', '-D_DEBUG', '-MDd', '/std:c++17'])
    else:
        env.Append(CCFLAGS = ['-O2', '-EHsc', '-DNDEBUG', '-MD', '/std:c++17'])

if env['target'] in ('debug', 'd'):
    cpp_library += '.debug'
else:
    cpp_library += '.release'

cpp_library += '.' + str(bits)
```

So then i changed the .cpp and .h files with the necessary code, they ended up like this:

### .CPP FILE:

```C++
#include "postgres.h"

using namespace godot;


// Convert C++ const char* to Godot::String
#define GOSTR(value) ( String( std::string( value ).c_str() ) )
// Convert Godot::String to C++ const char *
#define CSTR(value) ( value.alloc_c_string() )


void Postgres::_register_methods() {
    // register_method("_process", &Postgres::_process);
    // register_method("db_insert", &Postgres::db_insert);
    // register_method("db_update", &Postgres::db_update);
    // register_method("db_delete", &Postgres::db_delete);
    // register_method("db_upsert", &Postgres::db_upsert);
    register_method("remote_connect", &Postgres::remote_connect);
}

void Postgres::_init(){
    Godot::print(GOSTR("Hello World"));
}

Postgres::Postgres() {
    
}

Postgres::~Postgres() {
    // add your cleanup here
}

void Postgres::remote_connect(const String conn_str) {
    // initialize any variables here
    try
    {
        pqxx::connection conn = pqxx::connection(CSTR(conn_str));
    }
    catch(const std::exception& e)
    {
        Godot::print(GOSTR(e.what()));
    }
    
    
}
```

### .H FILE:

```C++
#ifndef POSTGRES_H
#define POSTGRES_H

#include <Godot.hpp>
#include <Reference.hpp>
#include <pqxx/pqxx>

namespace godot {

class Postgres : public Reference {
    GODOT_CLASS(Postgres, Reference)

private:

public:
    static void _register_methods();

    Postgres();
    ~Postgres();


    void _init(); // our initializer called by Godot
    void remote_connect(const String con_str);
    Dictionary db_insert(const String query);
    Dictionary db_update(const String query);
    Dictionary db_delete(const String query);
    Dictionary db_upsert(const String query); //INsert data if doesnt exist, or update if exists

};

}

#endif
```

### GDLIBRARY.CPP FILE:

```C++
#include "postgres.h"
using namespace godot;

extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
    godot::Godot::gdnative_init(o);
}

extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
    godot::Godot::gdnative_terminate(o);
}

extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
    godot::Godot::nativescript_init(handle);

    godot::register_class<Postgres>();
}
```

The src directory content is like this:

![image](https://user-images.githubusercontent.com/32317045/170595464-195aef53-43c0-40fd-893c-7735a29f75f7.png)

After All that was built using: 

```scons platform=windows target=release bits=64```

Every scons line was typed on ```x64 Native Tools Command Prompt for VS2019``` running as administrator

After that all dlls were linked in Godot so i clicked the gdexample.gdns file and in the editor inside Godot i typed on Script Class property Name "GDExample" and changed the Main.gd script to:

```GDScript
extends Node

var test = GDExample.new()

#func _on_Sprite_position_changed(node, new_pos):
#		print("The position of " + node.name + " is now " + str(new_pos))
```

the bug happened as soon as i opened the Godot project with the library files but then after i tried to run it crashed and reinforced the error.


### Minimal reproduction project

Couldn't upload the file (maybe it's too big) [73.1MB]

Here's a link:

https://ufile.io/ebcz844v