0

I use the following unmanaged code to search an IAccessible in an IAccessible tree, but the return IAccessible ansIacc in the managed side is always null.

unmanaged code(callee):

extern "C" __declspec(dllexport) HRESULT search(IAccessible * parent, BSTR bstrName, int role, int index_,
     _Out_ IAccessible* ansIacc, _Out_ int* left, _Out_ int* top, _Out_ int*width, _Out_ int* height)
{
       // the implementation of this function.
       // I have checked that the return value of left/top/width/height are right, 
       // but the ansIacc is null in the c# side
}

managed code(caller):

        [DllImport(@"C:\Users\jyppz\source\repos\server\x64\Debug\SearchIAcc.dll",
            CallingConvention = CallingConvention.StdCall)]
        static extern int search(IAccessible parent, [MarshalAs(UnmanagedType.BStr)] string bstrName, int role, int index, out object ansIacc, out int left, out int top, out int width, out int height);

        object ans = new object(); // I also have tried IAccessible ans = null 
                           // and Marshal's static method, but all failed.
        search((IAccessible)parent, accName_, accrole_, index_,
                        out ans, out top, out left, out width, out height);

        // the return ans is null !!!!!!!!!!!

Anyone can give some advice to improve the above code to return correct ans(search result)? Thanks.

JYP2011
  • 23
  • 5
  • 1
    Add `[MarshalAs(UnmanagedType.IUnknown)]` to the ansIacc parameter otherwise, it'll be considered as a VARIANT. – Simon Mourier May 21 '20 at 06:05
  • I follow you said to add [MarshalAs(UnmanagedType.IUnknown)], but System.Runtime.InteropServices.MarshalDirectiveException throwed @SimonMourier – JYP2011 May 21 '20 at 06:16
  • 1
    Actually, I hadn't noticed, but if ansIacc is an out pointer, it must be declared as `IAccessible**` ansIacc in C/C++ (and this has nothing to do with .NET) – Simon Mourier May 21 '20 at 06:47
  • you're right(according the declare of AccessibleObjectFromPoint from oleacc.dll), I have tried IAccessible** yesterday, but it doesn't help @SimonMourier and I change _Out_ IAccessible* ansIacc to _OutPtr_ IAccessible** ansIacc – JYP2011 May 21 '20 at 06:59
  • ```extern "C" __declspec(dllexport) HRESULT search(IAccessible * parent, BSTR bstrName, int role, int index_, _Outptr_ IAccessible** ansIacc, _Out_ int* left, _Out_ int* top, _Out_ int*width, _Out_ int* height)``` – JYP2011 May 21 '20 at 07:10
  • _Out_ or _Outptr_ are just annotations, this will not change anything. `IAccessible** ansIac` in native combined with `[MarshalAs(UnmanagedType.IUnknown)] out object ansIacc` in C# should work fine, or you're not showing all the code. – Simon Mourier May 21 '20 at 07:24
  • you're right. I assign ansIacc a value, instead of *ansIacc, so the returned value is null. After assign *ansIacc the searched targeted IAccessible, C# side return value is not null. So, does that means *ansIacc is the expected object in the C# side? @SimonMourier – JYP2011 May 21 '20 at 08:42
  • If you pass a null, yes, in C#, you will get a null reference on an IAccessible pointer. Otherwise, yes, if it says "System.__COMObject", it's an COM object (IAccessible reference). If you debug using Visual Studio, and enable native debugging and symbols downloads, you can even see the native pointer under the System.__COMObject. – Simon Mourier May 21 '20 at 09:11
  • I debug in the managed side, can I switch to native unmanaged side in virsual studio? If the answer is yes, that's fancy. But I don't know how to do it now. – JYP2011 May 21 '20 at 09:46
  • Sure, the debugger is cross languages/compilers. In VS, "Tools/Options/Debugging", uncheck "Enable Just My Code" and make sure in "Tools/Options/Debugging/Symbols" that you do download symbols ("Load all modules") from Microsoft Symbol Servers (note: it will take lots of time the first time as symbols can be big). In your .NET project Properties, in the Debug tab, check "Enable native code debugging" and you will be able to debug all layers – Simon Mourier May 21 '20 at 10:37
  • Ok, I will try it. Thanks very much – JYP2011 May 21 '20 at 12:32
  • Hi, bro. can you look this [question](https://stackoverflow.com/questions/61937422/how-to-check-two-iaccessible-are-identical-at-runtimeat-c-side)? I post it yesterday, but no one answers me now.@SimonMourier I google it, given the answer to use IObjectIdentity::IsEqualObject to compare two Com Object, but the return result is false. Sorry to interrupt you:-) – JYP2011 May 22 '20 at 02:45

0 Answers0