Skip to content

Commit fd3cd1a

Browse files
committed
Found a way to load k4abt from somewhere else
1 parent c2beafb commit fd3cd1a

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

Components/AzureKinect.BodyTracking.Visualizer.WPF/AzureKinect.BodyTracking.Visualizer.WPF.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
</PropertyGroup>
1414

1515
<ItemGroup>
16-
<PackageReference Include="Microsoft.Azure.Kinect.BodyTracking" Version="1.1.2" />
1716
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
1817
<PackageReference Include="Microsoft.Psi.Calibration" Version="0.19.100.1-beta" />
1918
<PackageReference Include="System.Composition" Version="8.0.0" />

Components/AzureKinect.BodyTracking/AzureKinect.BodyTracking.csproj

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,54 @@
99
<Nullable>enable</Nullable>
1010
<LangVersion>latest</LangVersion>
1111
<EmbedAllSources>true</EmbedAllSources>
12+
<BodyTrackerLibFolder>k4abt</BodyTrackerLibFolder>
1213
</PropertyGroup>
1314

1415
<ItemGroup>
1516
<PackageReference Include="MathNet.Spatial.Signed" Version="0.6.0" />
1617
<PackageReference Include="Microsoft.Azure.Kinect.BodyTracking" Version="1.1.2"/>
1718
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
1819
<PackageReference Include="System.Composition" Version="8.0.0"/>
20+
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
1921
</ItemGroup>
2022

2123
<ItemGroup>
2224
<ProjectReference Include="..\..\ComponentContract\ComponentContract.csproj" />
2325
</ItemGroup>
26+
27+
<!--Copy special DLLs to a subfolder.-->
28+
<ItemGroup>
29+
<!--NOTE: This native DLL loads ONNX runtime DLLs, so it also needs to be moved.-->
30+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking\1.1.2\lib\native\amd64\release\k4abt.dll">
31+
<Link>$(BodyTrackerLibFolder)\k4abt.dll</Link>
32+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
33+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
34+
</Content>
35+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking.onnxruntime\1.10.0\lib\native\amd64\release\onnxruntime.dll">
36+
<Link>$(BodyTrackerLibFolder)\onnxruntime.dll</Link>
37+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
38+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
39+
</Content>
40+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking.onnxruntime\1.10.0\lib\native\amd64\release\onnxruntime_providers_cuda.dll">
41+
<Link>$(BodyTrackerLibFolder)\onnxruntime_providers_cuda.dll</Link>
42+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
43+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
44+
</Content>
45+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking.onnxruntime\1.10.0\lib\native\amd64\release\onnxruntime_providers_shared.dll">
46+
<Link>$(BodyTrackerLibFolder)\onnxruntime_providers_shared.dll</Link>
47+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
48+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
49+
</Content>
50+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking.onnxruntime\1.10.0\lib\native\amd64\release\onnxruntime_providers_tensorrt.dll">
51+
<Link>$(BodyTrackerLibFolder)\onnxruntime_providers_tensorrt.dll</Link>
52+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
53+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
54+
</Content>
55+
<Content Include="$(NuGetPackageRoot)microsoft.azure.kinect.bodytracking.onnxruntime\1.10.0\lib\native\amd64\release\directml.dll">
56+
<Link>$(BodyTrackerLibFolder)\directml.dll</Link>
57+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
58+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
59+
</Content>
60+
</ItemGroup>
2461

25-
</Project>
62+
</Project>

Components/AzureKinect.BodyTracking/AzureKinectBodyTracker.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
using System.Collections.Generic;
33
using System.ComponentModel;
44
using System.Diagnostics;
5+
using System.IO;
56
using System.Runtime.CompilerServices;
7+
using System.Runtime.InteropServices;
68
using Microsoft.Azure.Kinect.BodyTracking;
79
using Microsoft.Azure.Kinect.Sensor;
810
using Microsoft.Extensions.Logging;
@@ -11,6 +13,10 @@
1113
namespace OpenSense.Components.AzureKinect.BodyTracking {
1214
public sealed class AzureKinectBodyTracker : INotifyPropertyChanged, IDisposable {
1315

16+
private const string K4abtLibDir = "k4abt";//Set in csproj
17+
18+
private const string K4abtDll = "k4abt.dll";
19+
1420
#region Options
1521

1622
private SensorOrientation sensorOrientation;
@@ -121,6 +127,7 @@ private void ProcessCalibration(Calibration calibration, Envelope envelope) {
121127
GpuDeviceId = GpuDeviceId,
122128
ModelPath = modelPath,
123129
};
130+
PreloadK4abtAndDependencies();
124131
/** NOTE:
125132
* AzureKinectBodyTrackingCreateException does not contain any error detail.
126133
* To know the detail, you need to look at its log.
@@ -196,6 +203,37 @@ private void SetProperty<T>(ref T field, T value, [CallerMemberName] string? pro
196203
}
197204
#endregion
198205

206+
#region P/Invoke
207+
208+
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
209+
private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
210+
211+
public static void PreloadK4abtAndDependencies() {
212+
var baseDir = AppContext.BaseDirectory;
213+
if (File.Exists(Path.Combine(baseDir, K4abtDll))) {
214+
/* NOTE:
215+
* Since the dependencies of k4abt.dll are located in both the application base directory and the AzureKinectLibs directory (LOAD_LIBRARY_SEARCH_USER_DIRS),
216+
* we need to enable both locations in the DLL search path.
217+
*
218+
* However, Windows only supports enabling or disabling directories for DLL searches—it does not allow us to explicitly define the search order between them.
219+
*
220+
* This means that if k4abt.dll exists in the application base directory, its dependencies (ONNX DLLs) will be loaded from the base directory, even if we explicitly load k4abt.dll from AzureKinectLibs.
221+
* This behavior is counterintuitive, but observed.
222+
*
223+
* As a result, we ensure that k4abt.dll does not exist in the application base directory.
224+
*/
225+
throw new Exception($"k4abt.dll exists in application base directory. It shouldn't be there.");
226+
}
227+
var extraDllDir = Path.Combine(baseDir, K4abtLibDir);
228+
var k4abtPath = Path.Combine(extraDllDir, K4abtDll);
229+
var handle = LoadLibraryEx(k4abtPath, IntPtr.Zero, 0);//We have to load this k4abt.dll, otherwise there is no chance our application knows it is there.
230+
if (handle == IntPtr.Zero) {
231+
int error = Marshal.GetLastWin32Error();
232+
throw new InvalidOperationException($"Failed to load k4abt.dll, error code: {error}");
233+
}
234+
}
235+
#endregion
236+
199237
#region IDisposable
200238
private bool disposed;
201239

WpfApplication/WpfApplication.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,14 @@
145145
<Resource Include="Resource\Icon\vflip.ico" />
146146
</ItemGroup>
147147

148+
<ItemGroup>
149+
<!--We have a special k4abt.dll in a special folder. This will cause issues.-->
150+
<FilesToRemove Include="$(OutputPath)k4abt.dll" Condition="'$(OutputPath)' != ''" />
151+
<FilesToRemove Include="$(PublishDir)k4abt.dll" Condition="'$(PublishDir)' != ''" />
152+
</ItemGroup>
153+
154+
<Target Name="RemoveUnwantedFiles" AfterTargets="Build;Publish">
155+
<Delete Files="@(FilesToRemove)" />
156+
</Target>
157+
148158
</Project>

0 commit comments

Comments
 (0)