-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Platform usage compatibility #104
Comments
@johnwc Yes! That is an example of where DNNE could be a good solution I think. In fact, I would really appreciate someone helping to validate more complex scenarios on the linux platform. Let me know if there is anything I can help with. |
Awesome! I will try to put something together to test within the next week or two, will get back with you. |
Is it possible to compile a linux library using VS in windows? Or do I need to be copying the files to a linux machine to compile it? |
@johnwc Nope. Unfortunately that is a really complicated issue. However, this has been asked before at #84 (comment) and I provided some details.
The DNNE tooling should "just work" on Linux as long as clang is on the path—typically the default once installed. Using gcc is possible using the following MSBuild property. Lines 51 to 54 in d48209b
The CI leg compiles and runs on Linux. DNNE/.github/workflows/main.yml Lines 10 to 25 in d48209b
|
I created a project and pushed it to GH. I was able to get just a plain sample to compile in linux. Then added the hooks.h include, received a lot of errors. Changed to to use g++ from clang, most of the errors disappeared. But now get this single error. Any ideas? My background: I am not at all new to programming. Just not very experienced in C++, but have done quite a bit with managed -> unmanaged calls. Have been developing in c# mostly for past 15 years, so feel free to get as technical as needed in conversation. $ dotnet build -c Release
Microsoft (R) Build Engine version 16.9.0+5e4b48a27 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
Building native export: "g++" -O2 -shared -fpic -D DNNE_ASSEMBLY_NAME=Test -D DNNE_COMPILE_AS_SOURCE -I "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform" -I "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native" -I "/usr/include/kea" -o "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/bin/TestNE.so" "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c" "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform/platform.c" -lstdc++ "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native/libnethost.a"
/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c: In function ‘int32_t FancyName(int32_t)’:
/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c(72,59): error G7E4560F8: invalid conversion from ‘void*’ to ‘int32_t (*)(int32_t)’ {aka ‘int (*)(int)’} [-fpermissive] [/home/jcarew/hooks/Test.csproj]
FancyName_ptr = get_fast_callable_managed_function(t1_name, methodName);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform/platform.c:34: warning: "_GNU_SOURCE" redefined
#define _GNU_SOURCE
<command-line>: note: this is the location of the previous definition
/home/jcarew/.nuget/packages/dnne/1.0.27/build/DNNE.targets(145,5): error MSB3073: The command ""g++" -O2 -shared -fpic -D DNNE_ASSEMBLY_NAME=Test -D DNNE_COMPILE_AS_SOURCE -I "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform" -I "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native" -I "/usr/include/kea" -o "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/bin/TestNE.so" "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c" "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform/platform.c" -lstdc++ "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native/libnethost.a" " exited with code 1. [/home/jcarew/hooks/Test.csproj]
Build FAILED.
/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c(72,59): error G7E4560F8: invalid conversion from ‘void*’ to ‘int32_t (*)(int32_t)’ {aka ‘int (*)(int)’} [-fpermissive] [/home/jcarew/hooks/Test.csproj]
/home/jcarew/.nuget/packages/dnne/1.0.27/build/DNNE.targets(145,5): error MSB3073: The command ""g++" -O2 -shared -fpic -D DNNE_ASSEMBLY_NAME=Test -D DNNE_COMPILE_AS_SOURCE -I "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform" -I "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native" -I "/usr/include/kea" -o "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/bin/TestNE.so" "/home/jcarew/hooks/obj/x64/Release/net5.0/dnne/Test.g.c" "/home/jcarew/.nuget/packages/dnne/1.0.27/tools/platform/platform.c" -lstdc++ "/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.centos.8-x64/5.0.12/runtimes/centos.8-x64/native/libnethost.a" " exited with code 1. [/home/jcarew/hooks/Test.csproj]
0 Warning(s)
2 Error(s)
Time Elapsed 00:00:02.86 |
@johnwc The issue above is that you are using |
@johnwc The precise issue at hand here is that C++ has stricter casting rules than C99. The reasoning behind using C99 instead of C++ is it is the lingua franca for most of this embedding work. C++ has some subtle issues that can surprise and making a "safe" C++ API is non-trivial and generally winds up being mostly C with some C++ niceties. Unfortunately, these niceties typically introduce C++ features that aren't expected or desired (e.g., exceptions). |
I'm currently looking at the |
@johnwc I added a build/test for both gcc and g++ on Linux. This required supporting compiling and linking as C++. I've only added testing for g++ but will likely add more. A new package with these changes has been published, https://www.nuget.org/packages/DNNE/1.0.28. |
Way easier than I thought. There are now tests for compiling as C++ on all platforms. |
This is great! With that update, I was able to create the version() method and return the same value that is set for KEA_HOOKS_VERSION in the hooks.h. I also added a simple File.AppendAllLines to the method to have a log to prove it was being called. I compiled just fine, and worked as a a hook when configured and the service restarted. I will attempt to write a simple command hook and see how it goes. |
@AaronRobinsonMSFT how do I handle the |
@johnwc This will get very complex and depend on how the Kea types want to be projected into managed code. In this case, the unsafe struct LibraryHandle
{
// This function pointer can be acquired via a DllImport to dlsym, GetProcAddress, or the NativeLibrary API.
// Another approach would be to create a DllImport into the generated native binary being compiled by DNNE.
// Then pass all the parts back into native code and make the call as expected.
// See the readme about overriding dnne_abort. The point here is you can pass a .c or .cpp file
// to compile into the generated native component and then DllImport into that function.
private static ??? registerCalloutFptr;
public static void registerCallout(LibraryHandle* h, string name, delegate*<void*, int> callout)
{
// Marshal the string to an byte* using System.Text.UTF8Encoding and a fixed statement.
UTF8Encoding utf8 = new();
byte[] encodedBytes = utf8.GetBytes(name);
fixed (byte* b = encodedBytes)
registerCalloutFptr(h, b, callout);
}
}
[UnmanagedCallersOnly]
private static unsafe int Callback(void* ptr)
{
return 0;
}
[UnmanagedCallersOnly]
public static unsafe ??? load(void* libhandle)
{
LibraryHandle* h = (LibraryHandle*)libhandle;
LibraryHandle.registerCallout(h, "name", &Callback);
...
} A quick note. The C++ reference (i.e., |
Sounds like I will have to create proxy methods like described here. class Foo {
public:
int Bar(int a, int b);
};
// Proxy methods
extern "C" int Foo_Bar(Foo* pFoo, int a, int b) { return pFoo->Bar(a, b); } static class NativeFoo {
[DllImport("Foo", EntryPoint = "Foo_Bar")]
public static extern int Bar(IntPtr obj, int a, int b);
} |
With this package, would we be able to develop a hook library for the kea dhcp server for linux? If so, we would be willing to create one and share it on gtihub as a good real-world working example for others to learn.
Hooks Developer's Guide
The text was updated successfully, but these errors were encountered: