diff --git a/clr_loader/netfx.py b/clr_loader/netfx.py index 24460ca..4efe841 100644 --- a/clr_loader/netfx.py +++ b/clr_loader/netfx.py @@ -14,13 +14,15 @@ def __init__( ): initialize() if config_file is not None: - config_file_s = str(config_file) + config_file_s = str(config_file).encode("utf8") else: config_file_s = ffi.NULL + domain_s = domain.encode("utf8") if domain else ffi.NULL + self._domain_name = domain self._config_file = config_file - self._domain = _FW.pyclr_create_appdomain(domain or ffi.NULL, config_file_s) + self._domain = _FW.pyclr_create_appdomain(domain_s, config_file_s) def info(self) -> RuntimeInfo: return RuntimeInfo( @@ -41,6 +43,11 @@ def _get_callable(self, assembly_path: StrOrPath, typename: str, function: str): function.encode("utf8"), ) + if func == ffi.NULL: + raise RuntimeError( + f"Failed to resolve {typename}.{function} from {assembly_path}" + ) + return func def shutdown(self): diff --git a/netfx_loader/ClrLoader.cs b/netfx_loader/ClrLoader.cs index af89cee..32b4c01 100644 --- a/netfx_loader/ClrLoader.cs +++ b/netfx_loader/ClrLoader.cs @@ -32,8 +32,10 @@ public static IntPtr CreateAppDomain( { var setup = new AppDomainSetup { + ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, ConfigurationFile = configFile }; + Print($"Base: {AppDomain.CurrentDomain.BaseDirectory}"); var domain = AppDomain.CreateDomain(name, null, setup); Print($"Located domain {domain}"); diff --git a/tests/test_common.py b/tests/test_common.py index a33dec0..8a9e36d 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -76,27 +76,15 @@ def test_coreclr(example_netcore: Path): def test_coreclr_properties(example_netcore: Path): - from multiprocessing import get_context - - p = get_context("spawn").Process( - target=_do_test_coreclr_autogenerated_runtimeconfig, - args=(example_netstandard,), - kwargs=dict(properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore))), + run_in_subprocess( + _do_test_coreclr_autogenerated_runtimeconfig, + example_netstandard, + properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore)), ) - p.start() - p.join() - p.close() def test_coreclr_autogenerated_runtimeconfig(example_netstandard: Path): - from multiprocessing import get_context - - p = get_context("spawn").Process( - target=_do_test_coreclr_autogenerated_runtimeconfig, args=(example_netstandard,) - ) - p.start() - p.join() - p.close() + run_in_subprocess(_do_test_coreclr_autogenerated_runtimeconfig, example_netstandard) def _do_test_coreclr_autogenerated_runtimeconfig( @@ -114,25 +102,31 @@ def _do_test_coreclr_autogenerated_runtimeconfig( sys.platform != "win32", reason=".NET Framework only exists on Windows" ) def test_netfx(example_netstandard: Path): - from clr_loader import get_netfx - - netfx = get_netfx() - asm = netfx.get_assembly(example_netstandard / "example.dll") - - run_tests(asm) + run_in_subprocess(_do_test_netfx, example_netstandard) @pytest.mark.skipif( sys.platform != "win32", reason=".NET Framework only exists on Windows" ) def test_netfx_chinese_path(example_netstandard: Path, tmpdir_factory): - from clr_loader import get_netfx - tmp_path = Path(tmpdir_factory.mktemp("example-中国")) shutil.copytree(example_netstandard, tmp_path, dirs_exist_ok=True) - netfx = get_netfx() - asm = netfx.get_assembly(os.path.join(example_netstandard, "example.dll")) + run_in_subprocess(_do_test_netfx, tmp_path) + + +@pytest.mark.skipif( + sys.platform != "win32", reason=".NET Framework only exists on Windows" +) +def test_netfx_separate_domain(example_netstandard): + run_in_subprocess(_do_test_netfx, example_netstandard, domain="some domain") + + +def _do_test_netfx(example_netstandard, **kwargs): + from clr_loader import get_netfx + + netfx = get_netfx(**kwargs) + asm = netfx.get_assembly(example_netstandard / "example.dll") run_tests(asm) @@ -142,3 +136,12 @@ def run_tests(asm): test_data = b"testy mctestface" res = func(test_data) assert res == len(test_data) + + +def run_in_subprocess(func, *args, **kwargs): + from multiprocessing import get_context + + p = get_context("spawn").Process(target=func, args=args, kwargs=kwargs) + p.start() + p.join() + p.close()