Potential Bug in C#-Api: Different behavior in generating context key as bytes array (SaveContextToArray)

Potential Bug in C#-Api: Different behavior in generating context key as bytes array (SaveContextToArray)

PanWauu
Contributor Contributor
701 Views
5 Replies
Message 1 of 6

Potential Bug in C#-Api: Different behavior in generating context key as bytes array (SaveContextToArray)

PanWauu
Contributor
Contributor

Hi all,

 

I am struggling with reference keys in inventor. I boiled it down to a simple (reproduzible) procedure: 

1) Get a selected Edge and unselect it

2) Get the reference key and context key of this edge

3) Print generated keys as string

4) Act is if i loaded those from a file and create a new context from the context key

5) Trace the reference key with the new context back to the edge and select it

 

I wrote the program in C# and VBA. You can see both programms below.  In VBA it works fine, in C# it breaks. When analyzing the generated keys one can see that the generated context keys are very different. Much shorter for the C# program. When I am loading the VBA strings in C# the program runs without problems. So the problem is that the context key as byte array is wrong in C#.

 

Is there a bug in the program? Does somebody know a workaround in C# maybe? Can I call one line of VBA from C#?

 

Thanks for every idea!

 

Output of context and reference strings:

 

 

 

 

 

Keys printed by C#:
AgAAAAEAAAA=
AgECACgAAAACAQEACAAAAC0AAAADAAAAAQQBABAAAAAAAAAAAgAAAAQAAAAGAAAA

Keys printed by VBA:
AgAAAAAAAACewiuk1BHoAWAALbPuKfuwBAAAG0AAAIgsAXheY2BkYHhr7nzgsqAsXwIDww6jKe0bGBgYIRAot1F3D+cFQfk3DBx3NljbreCEyTEB5TZhyDEAAQsQhzCkMhQzlDD8827M/+GkYuNgsWWFiSDzP0YmBoYGZqBWJ4WXZy4KHi1k4Fi+y2jxHU4mqJUsQLkyjyCgXIQ7A0cbWA5iJVAFUA5mAcgSEJcZaB7QTJClDUA2AyuQBsmxAWlWoAKORSx6ug6m/YeXiy6qmL/NjxlqDxtQrq+vOOyiYHEoA8cEsD1QTzOwA+VOTZ/z/aJgrycDRzuSGxgZOIBy9w4tv3NRsBsuxwI2k4kB5HaQm4DuMQC5iR2IOYBYF+JOIIkJQHpAAKQHxIRyBTqA7P9AAJLjAmJgIOAEQIczLD3kyqbhtvuZ7Mq3CxWKzplC3MTIwAWUW2vwg1fOZdOEP3mFnc7K6WBbQJAbKPfm4rm6i4I9cL+wQf0C8icwLKnuF5gneHD6BiIB8hOt7AeFpwgB+3mA9stobJnN5KGzQr07YMa/63orYGHKC5Rb5bhr50XBDHjagaVfPqCcGkOEG3LagcgxgdMOEJEbpg1QvWAalJGwJhhQwgNlMhDNDGKAcwUe1WCVIAAKFhDGB0BJEpR0IAAA7geThw==
AgECACgAAAACAQEACAAAAC0AAAADAAAAAQQBABAAAAAAAAAAAgAAAAQAAAAGAAAA

 

 

 

 

 

 

C#-Code:

 

 

 

 

 

// Get the active document and a selected edge
var assemblyDocument = (AssemblyDocument)_invAPI.getActiveDocument(_invAPI.InvApp);
var selectSetEnumerator = assemblyDocument.SelectSet.GetEnumerator();
selectSetEnumerator.MoveNext();
var currentEdgeProxy = (EdgeProxy)selectSetEnumerator.Current;

// Clear selection
assemblyDocument.SelectSet.Clear();

// Get keys of reference and context
var keyManager = assemblyDocument.ReferenceKeyManager;
int context = keyManager.CreateKeyContext();

// Get keys of reference and context
byte[] contextBytes = new byte[1];
keyManager.SaveContextToArray(context, ref contextBytes);
byte[] referenceBytes = new byte[1];
currentEdgeProxy.GetReferenceKey(ref referenceBytes, context);

// Act as if i saved and loaded the keys
Debug.WriteLine(keyManager.KeyToString(contextBytes));
Debug.WriteLine(keyManager.KeyToString(referenceBytes));

//  Load new context from context key - WITHOUT THIS LINE IT WORKS IN C#
context = keyManager.LoadContextFromArray(ref contextBytes);

// Find new edge from reference key with new context - FAILS IN C#
object entity = keyManager.BindKeyToObject(ref referenceBytes, context, out object MatchType);

assemblyDocument.SelectSet.Select(entity);

 

 

 

 

 

 

VBA-Code:

 

 

 

 

 

Public Sub TestReferenceKey()
    ' Get the active document and a selected edge
    Dim assemblyDocument As Document
    Set assemblyDocument = ThisApplication.ActiveDocument
    Dim edgeProxy As edgeProxy
    Set edgeProxy = assemblyDocument.SelectSet.Item(1)
    
    ' Clear selection
    assemblyDocument.SelectSet.Clear
    
    ' Get key manager and create a new context
    Dim keyManager As ReferenceKeyManager
    Set keyManager = assemblyDocument.ReferenceKeyManager
    
    Dim context As Long
    context = keyManager.CreateKeyContext
    
    ' Get keys of reference and context
    Dim referenceBytes() As Byte
    Call edgeProxy.GetReferenceKey(referenceBytes, context)

    Dim contextBytes() As Byte
    Call keyManager.SaveContextToArray(context, contextBytes)
    
    ' Act as if i saved and loaded the keys
    Debug.Print keyManager.KeyToString(contextBytes)
    Debug.Print keyManager.KeyToString(referenceBytes)
    
    ' Load new context from context key
    context = keyManager.LoadContextFromArray(contextBytes)
    
    ' Find new edge from reference key with new context
    Dim foundEdge As Edge
    Set foundEdge = keyManager.BindKeyToObject(referenceBytes, context)
    
    ' Select edge again
    assemblyDocument.SelectSet.Select foundEdge
End Sub

 

 

 

 

 

 

 

PS:

Edit 1: Added print of context and reference keys as string and the resulting strings

Edit 2: Rewrite with the problem being the context key generation

0 Likes
Accepted solutions (1)
702 Views
5 Replies
Replies (5)
Message 2 of 6

matt_jlt
Collaborator
Collaborator

I could be wrong as i am not too familiar with C#, but maybe try to not specify the byte array length on the reference key byte arrays. 

 

= new byte[] { };

 

Also, maybe define the edge as an inventor.edgeproxy object See if that helps.

Message 3 of 6

PanWauu
Contributor
Contributor
This did not change anything in my case. The edge is already casted to EdgeProxy and the bytes are overwritten anyways.
While testing your suggestion, I also noticed that the context strings between the programms are quite different! I edited the original post to include this info.
Do you see a problem with the generation of the context?
0 Likes
Message 4 of 6

PanWauu
Contributor
Contributor

BTW when adapting the code for parts (Change "AssemblyDocument" to "PartDocument" and "EdgeProxy" to "Edge") both programs also return different context keys but the C# programm still is not able to recover the edge.

I tried to use the VBA generated Keys in C# and can recover the edge there. So the problem is the context key in bytes in C#. I will edit the original question

0 Likes
Message 5 of 6

PanWauu
Contributor
Contributor

I am still struggling with this issue. In short when I try to save the context to string I get different results in c# and vba. Glad for any help or also validation that this is a bug

0 Likes
Message 6 of 6

PanWauu
Contributor
Contributor
Accepted solution

I solved my problem myself now. I did not have a sufficient understanding of the reference keys. Sadly my "exactly mirrored" code examples of C# and VB contain a difference. In VB i first generate a reference key in the context and then save the context. In C# i first save the context and then generate a reference key. Apperantly the generation of reference keys does ALTER the context and because of that the order of calls does matter.

0 Likes