Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions tests/projects/csharp/pinvoke/src/app/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Runtime.InteropServices;

[DllImport("mathlib")]
static extern int add(int a, int b);

[DllImport("mathlib")]
static extern int multiply(int a, int b);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The string literal "mathlib" is repeated across multiple DllImport attributes. Repeating such literals can lead to maintainability issues; if the native library's name changes, it would require updating multiple locations. It is a good practice to define such values as a const string in a dedicated static class for P/Invoke declarations to centralize the definition and improve code organization.

For example, you could refactor these declarations into a NativeMethods class:

internal static class NativeMethods
{
    private const string NativeLib = "mathlib";

    [DllImport(NativeLib)]
    internal static extern int add(int a, int b);

    [DllImport(NativeLib)]
    internal static extern int multiply(int a, int b);
}

This approach enhances maintainability and provides a clear separation for native interop declarations.


int sum = add(3, 4);
int product = multiply(5, 6);
Console.WriteLine($"add(3,4)={sum}");
Console.WriteLine($"multiply(5,6)={product}");
13 changes: 13 additions & 0 deletions tests/projects/csharp/pinvoke/src/native/mathlib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __attribute__((visibility("default")))
#endif

EXPORT int add(int a, int b) {
return a + b;
}

EXPORT int multiply(int a, int b) {
return a * b;
}
13 changes: 13 additions & 0 deletions tests/projects/csharp/pinvoke/test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import("detect.sdks.find_dotnet")

function test_build(t)
if is_subhost("msys") then
return t:skip("csharp not supported on msys")
end
local dotnet = find_dotnet()
if dotnet and dotnet.sdkver then
t:build()
else
return t:skip("dotnet sdk not found")
end
end
10 changes: 10 additions & 0 deletions tests/projects/csharp/pinvoke/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_rules("mode.debug", "mode.release")

target("mathlib")
set_kind("shared")
add_files("src/native/*.c")

target("app")
set_kind("binary")
add_deps("mathlib")
add_files("src/app/*.cs")
13 changes: 13 additions & 0 deletions xmake/rules/csharp/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,17 @@ function main(target)
end, {dependfile = dependfile, files = sourcefiles, values = depcsproj})

target:data_set("csharp.csproj", csprojfile)

-- add native shared library search paths for P/Invoke
for _, dep in ipairs(target:orderdeps()) do
if dep:is_shared() and not dep:rule("csharp.build") then
if is_host("windows") then
target:add("runenvs", "PATH", dep:targetdir())
elseif is_host("macosx") then
target:add("runenvs", "DYLD_LIBRARY_PATH", dep:targetdir())
else
target:add("runenvs", "LD_LIBRARY_PATH", dep:targetdir())
end
end
end
end
Loading