Skip to content

Calling overridden method with out parameter from C# to python results in 0xC0000005 (Access Violation) #1481

Closed

Description

@roy-van-de-korput

Environment

  • Pythonnet version: 2.5.2
  • Python version: 3.8.3
  • Operating System: Win10 64bit
  • .NET Runtime: 4.8

Details

  • Describe what you were trying to get done.

In C# I have defined an interface with a method with an out parameter. I implemented this interface in python, an now I want to call this method from C#. (using pythonnet)

What I see is that a method without out parameter works fine, but a method with an out parameter throws an access violation.

I know that out parameters are handled differently in pythonnet: you return a tuple with first the return value and the second tuple item is the out parameter.

My C# code

public interface IMyInterface
{
    string MyMethod_Out(string name, out int index);
    string MyMethod(string name);
}

public class MyServer
{
    public void CallMyMethod_Out(IMyInterface myInterface)
    {
        Console.WriteLine("C#.CallMyMethod_Out: before MyMethod_Out");
        int index = 1;
        myInterface.MyMethod_Out("myclient", out index);
        Console.WriteLine($"C#:CallMyMethod_Out: after MyMethod_Out: index:{index}");
    }
    
    public void CallMyMethod(IMyInterface myInterface)
    {
        Console.WriteLine("C#.CallMyMethod: before MyMethod");
        myInterface.MyMethod("myclient");
        Console.WriteLine($"C#:CallMyMethod: after MyMethod");
    }

    public void DoSomething()
    {
        Console.WriteLine("C#.DoSomething");
    }
}

My Python code:

import clr
import sys

sys.path.append('some_dir')
clr.AddReference("ClassLibrary1")

from ClassLibrary1 import IMyInterface, MyServer

class MyInterfaceImpl(IMyInterface):
    __namespace__ = "ClassLibrary1"

    def MyMethod_Out(self, name, index):
        print("Python.MyInterfaceImpl.MyMethod_Out")
        other_index = 101
        return ('MyName', other_index)

    def MyMethod(self, name):
        print("Python.MyInterfaceImpl.MyMethod")
        return 'MyName'

print('\nCall regular C# function')
my_server = MyServer()
my_server.DoSomething()

my_interface_impl = MyInterfaceImpl()

print('\nCall without out param')
my_server.CallMyMethod(my_interface_impl)

print('\nCall with out param')
my_server.CallMyMethod_Out(my_interface_impl) # Access Violation 0xC0000005
  • If there was a crash, please include the traceback here.
    Output:

Call regular C# function
C#.DoSomething

Call without out param
C#.CallMyMethod: before MyMethod
Python.MyInterfaceImpl.MyMethod
C#:CallMyMethod: after MyMethod

Call with out param
C#.CallMyMethod_Out: before MyMethod_Out
Process finished with exit code -1073741819 (0xC0000005)

Expected output

...
Call with out param
C#.CallMyMethod_Out: before MyMethod_Out
Python.MyInterfaceImpl.MyMethod_Out
C#:CallMyMethod_Out: after MyMethod_Out: index:101

Activity

  1. filmor commented on Jul 6, 2021

    @filmor
    Member

    Can you please test this with the current master? I vaguely remember a similar issue that has been fixed a while ago.

  2. roy-van-de-korput commented on Jul 6, 2021

    @roy-van-de-korput
    Author

    I just retried with master (ea61b03) . Same error.

  3. default-writer commented on Dec 4, 2021

    @default-writer

    You are not just override method, you are returning Tuple instead of a String, what whould you expect for that?

    return type String:
    string MyMethod_Out(string name, out int index);

    return type Tuple<String,Int>
    return ('MyName', other_index)

  4. added this to the 3.0.0 milestone on Jan 6, 2022
  5. lostmsu commented on Jan 6, 2022

    @lostmsu
    Member

    This is a very involved issue, that requires dynamic code generation to be rewritten to support byref arguments. For now unless somebody wants to pick it up, I suggest we document it and move along.

    As a workaround one can define another interface in .NET that does not have out or ref parameters, and a class serving as an adapter between the original interface and the new one.

  6. lostmsu commented on Jan 6, 2022

    @lostmsu
    Member

    😁 I got bored and made #1663

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions