dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.96k stars 4.65k forks source link

Hosting .NET Core using nethost and hostfxr - Problem linking with libnethost.lib #59143

Closed lissity closed 2 years ago

lissity commented 3 years ago

I'm trying to statically link nethost to my application using libnethost.lib. I've written the following small program:

#include <iostream>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
#include <Windows.h>
#include <coreclr_delegates.h>
#include <hostfxr.h>
#include <nethost.h>

int main()
{
    // Pre-allocate a large buffer for the path to hostfxr
    char_t buffer[MAX_PATH];
    size_t buffer_size = sizeof(buffer) / sizeof(char_t);
    int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
    if (rc != 0)
        return false;
}

When building I get the error: Error LNK2019 unresolved external symbol __imp_get_hostfxr_path referenced in function main

I'm using the libnethost.lib from C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\5.0.9\runtimes\win-x64\native. I'm building my code for x64 platform in Debug mode in Visual Studio 2019.

When linking to the dynamic library (nethost.lib/nethost.dll) everything works as expected, and I can build and run the program. But when I try to statically link with libnethost.lib I get the error.

What is wrong and how should I fix it?

dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

am11 commented 3 years ago

fwiw, your example works on unix using libnethost.a:

$ cat > foo.cpp <<EOF
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <coreclr_delegates.h>
#include <hostfxr.h>
#include <nethost.h>

#define _POSIX_C_SOURCE 1
#include <limits.h>

int main()
{
    // Pre-allocate a large buffer for the path to hostfxr
    char_t buffer[PATH_MAX];
    size_t buffer_size = sizeof(buffer) / sizeof(char_t);
    int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
    if (rc != 0)
    {
        printf("get_hostfxr_path failed :(\n");
        return -1;
    }
    printf("get_hostfxr_path returned: %s\n", buffer);
    return 0;
}
EOF

$ clang++ -I ~/.dotnet7/packs/Microsoft.NETCore.App.Host.osx-x64/7.0.0-alpha.1.21425.4/runtimes/osx-x64/native/ \
    ~/.dotnet7/packs/Microsoft.NETCore.App.Host.osx-x64/7.0.0-alpha.1.21425.4/runtimes/osx-x64/native/libnethost.a \
    foo.cpp

$ ./a.out
get_hostfxr_path returned: /usr/local/share/dotnet/host/fxr/5.0.9/libhostfxr.dylib
ghost commented 3 years ago

Tagging subscribers to this area: @vitek-karas, @agocke, @vsadov See info in area-owners.md if you want to be subscribed.

Issue Details
I'm trying to statically link `nethost` to my application using `libnethost.lib`. I've written the following small program: ``` #include #include #include #include #include #include #include #include #include #include #include int main() { // Pre-allocate a large buffer for the path to hostfxr char_t buffer[MAX_PATH]; size_t buffer_size = sizeof(buffer) / sizeof(char_t); int rc = get_hostfxr_path(buffer, &buffer_size, nullptr); if (rc != 0) return false; } ``` When building I get the error: `Error LNK2019 unresolved external symbol __imp_get_hostfxr_path referenced in function main` I'm using the `libnethost.lib` from `C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\5.0.9\runtimes\win-x64\native`. I'm building my code for x64 platform in Debug mode. When linking to the dynamic library (`nethost.lib`/`nethost.dll`) everything works as expected, and I can build and run the program. But when I try to statically link with `libnethost.lib` I get the error. What is wrong and how should I fix it?
Author: lissity
Assignees: -
Labels: `area-Host`, `untriaged`
Milestone: -
rseanhall commented 3 years ago

You have to opt-in for statically linking.

#define NETHOST_USE_AS_STATIC
#include <nethost.h>

https://github.com/dotnet/runtime/blob/e47728f7855c530a5779487058de8c1de7c77046/src/native/corehost/nethost/nethost.h#L13-L19

lissity commented 2 years ago

Aha, I see. I was apparently using an older version of nethost.h so I missed that there was such an define. After updating my nethost.h and defining NETHOST_USE_AS_STATIC I can now statically link with nethost. Thank you for the help!