Skip to content

Support pythonnet for AppDomain #78

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

koubaa
Copy link
Contributor

@koubaa koubaa commented Jul 24, 2025

Related to pythonnet/pythonnet#2053
Fixes #53

When using domain.Load for an assembly, the assembly resolution rules are awkward Even if the full path is given to the AssemblyName, when the domain tries to load the assembly, it does not use that context and tries to resolve the assembly using normal domain resolution rules, which would require an assembly resolver to be installed. However, the assembly resolver that is actually used at runtime is the one installed to the main appdomain.

This prevents a library like Python.Runtime.dll (used by pythonnet) which is not installed to the application base directory to be loaded by clr_loader.

It is possible for an assembly to run code in another appdomain (using DoCallBack), but only if that assembly is reachable from the BaseDirectory. ClrLoader was not reachable because the base directory was hardcoded to that which contained python.exe, and ClrLoader.dll is not found there. I fixed this by making the folder which contains ClrLoader.dll the BaseDirectory for app domains created by ClrLoader.

To fix this issue, the assembly resolver of the main appdomain is lazily extending to include paths needed for libraries passed into GetFunction, and GetFunction internally uses AppDomain.DoCallBack() to marshal the function pointer inside the target app domain, using global domain data to access the function pointer and return it to the user of clr_loader.

With these changes, the following block:

import clr_loader
netfx = clr_loader.get_netfx(domain="Python", config_file=config_file)
from pythonnet import load
load(netfx)
import System
print(System.AppDomain.CurrentDomain.FriendlyName)

will print "Python"

@filmor
Copy link
Member

filmor commented Jul 24, 2025

Very nice, thank you! I'll fix the CI on master s.t. you can rebase on that.

When using domain.Load for an assembly, the assembly resolution rules are awkward
Even if the full path is given to the AssemblyName, when the domain tries to load
the assembly, it does not use that context and tries to resolve the assembly using
normal domain resolution rules, which would require an assembly resolver to be
installed. However, the assembly resolver that is actually used at runtime is the
one installed to the main appdomain.

This prevents a library like Python.Runtime.dll (used by pythonnet) which
is not installed to the application base directory to be loaded by clr_loader.

To fix this issue, the assembly resolver of the main appdomain is lazily
extending to include paths needed for libraries passed into GetFunction,
and GetFunction internally uses AppDomain.DoCallBack() to marshal the
function pointer inside the target app domain, using global domain data
to access the function pointer and return it to the user of clr_loader.
@filmor filmor force-pushed the get-functor-in-domain branch from e3b043b to f58e574 Compare July 24, 2025 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error loading clr into non-root domain
2 participants