- Notifications
You must be signed in to change notification settings - Fork748
[Looking for Suggestion] Unable to find assembly: SkiaSharp#2589
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
(Originally an issue:#2588) Hi, thanks for the great library! It has been tremendously helpful in both my personal and professional life! Right now I am encountering a problem that might not be pythonnet specific but is not obvious to solve and encountered when I use Pythonnet. Specifically, when my project references SkiaSharp which contains native dlls, pythonnet will not be able to load everything properly - it locates the entry assembly fine, but the dependencies are not loaded. The initial import is ok but during runtime an exception is thrown. Would love to hear any suggestions on solving this problem. Environment
Below is the entry assembly, which directly references SkiaSharp. <ProjectSdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReferenceInclude="SkiaSharp"Version="3.119.0" /> </ItemGroup></Project> usingSkiaSharp;namespacePythonNetSkiaSharpProblem{publicclassProgram{publicstaticvoidMain(string[]args){try{varinfo=newSKImageInfo(width:64,height:64);usingvarsurface=SKSurface.Create(info);SKCanvascanvas=surface.Canvas;canvas.Clear(newSKColor(red:0,green:200,blue:200,alpha:255));usingSKImageimage=surface.Snapshot();usingSKDatapngData=image.Encode(SKEncodedImageFormat.Png,quality:100);conststringoutputPath="filled64.png";usingvarstream=File.OpenWrite(outputPath);pngData.SaveTo(stream);System.Console.WriteLine($"Saved{outputPath}");}catch(Exceptione){Console.WriteLine(e);}}}} And this is how I am referencing the entry assembly,from some location outside the published folder (notice the same problem happens even if this script is placed directly inside the published folder). importsyssys.path.insert(0,r"C:\Users\Charles Zhang\Desktop\Temp\PythonNetSkiaSharpProblem\PythonNetSkiaSharpProblem\bin\Debug\net8.0")importpythonnetpythonnet.load("coreclr")importclrclr.AddReference("PythonNetSkiaSharpProblem")fromPythonNetSkiaSharpProblemimportProgramProgram.Main([])# Exception in stack Output:
This is likely due to this folder structure:
See:https://github.com/Charles-Zhang-Python/PythonNetSkiaSharpProblem This might be related to#468 but is somewhat different since I am not loading the dll directly, and everything is .Net 8 properly. |
BetaWas this translation helpful?Give feedback.
All reactions
Replies: 2 comments 2 replies
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Notice a workaround is to copy |
BetaWas this translation helpful?Give feedback.
All reactions
-
|
BetaWas this translation helpful?Give feedback.
All reactions
-
I tried it, publishing as |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Hi@filmor, thanks for the reply. I've fixed the repo link. I am aware that dotnet publish with a target runtime will work. That's because it will copy the specific dlls to the root folder. It's however just workarounded the problem, rather than fixed it. Like I commented out above. Regarding "You are creating an executable, not a library", that shouldn't be a problem since in dotnet all executables are just dlls, the In the meantime, I did find a more robust way to load the dlls from the python side. One workaround is to add below class and make available to python script: publicsealedclassPluginLoadContext:AssemblyLoadContext{readonlyAssemblyDependencyResolverresolver;publicPluginLoadContext(stringpluginMainDll)=>resolver=new(pluginMainDll);protectedoverrideAssembly?Load(AssemblyNamename)=>resolver.ResolveAssemblyToPath(name)is{}p?LoadFromAssemblyPath(p):null;protectedoverrideIntPtrLoadUnmanagedDll(stringlibName)=>resolver.ResolveUnmanagedDllToPath(libName)is{}p?LoadUnmanagedDllFromPath(p):IntPtr.Zero;} Then, instead of loading using clr.AddReference, call below: ctx=PluginLoadContext(str(dll_path))asm=ctx.LoadFromAssemblyPath(str(dll_path))# Equivalent to clr.AddReference(asm), notice "import" works out of the box due to Pythonnet's hook into the import process |
BetaWas this translation helpful?Give feedback.
All reactions
This discussion was converted from issue #2588 on May 02, 2025 13:13.