MIDL marshaling array of structures using size_is in unmanaged c++ - midl

I’m trying to retrieve an array of structures through a COM interface. It works when the number of structures is 1. When the number of structures is greater than 1, only the first structure is marshaled correctly. The remaining structures in the array have garbage data.
My interface looks like this:
typedef struct tagINTOBJINTERFACE
{
long lObjectId;
IMyObject* pObj;
} INTOBJINTERFACE;
[
object,
uuid(<removed>),
dual,
nonextensible,
helpstring("Interface"),
pointer_default(unique)
]
interface IMyInterface : IUnknown {
HRESULT CreateObjects(
[in] VARIANT* pvDataStream,
[out]long* Count,
[out,size_is(,*Count)] INTOBJINTERFACE** ppStruct
);
};
I allocate the structure memory like this:
long lCountInterfaces = listInterfaces.GetCount();
long lMemSize = lCountInterfaces * sizeof(INTOBJINTERFACE);
INTOBJINTERFACE* pstruct = (INTOBJINTERFACE*) CoTaskMemAlloc( lMemSize );
And then fill in the members of each structure in the array. I can see in the debugger that all members of all array elements are properly assigned.
After filling in the structures, I assign “*ppStruct = pstruct” to pass the array out.
I can also see that the out parameter “*Count” is properly set to the correct number of elements.
Why doesn’t this work?

Reason:
Your application uses the universal marshaller from windows for mashalling.
The universal marshaller reads the meta data from your typelib (*.tlb).
The generated typelib doesn't support size_is.
Todo:
You should use the Proxy/Stub dll generated by Visual Studio (...PS project).
- Build the Proxy/Stub dll
- call "regsvr32 "
- remove the "TypeLib = s '{?????-...-????}'" entry from your servers "*.rgs"
file

In addition to Joerg's answer that using size_is is not possible, here is what's possible: SAFEARRAY.
Keywords: Safearray of UDT
Explanation and examples are here
Short summary:
Define structure with a GUID.
Create object of type IRecordInfo that describes your structure using the type library.
Use SafeArrayCreateEx to create SAFEARRAY of type VT_RECORD.
Fill it with data.
Retrieve on the other side.

Related

Creating a structure within a structure with a dynamic name

I have large data sets which i want to work with in matlab.
I have a struct called Trail containing serveral structures called trail1, trail2 ...
which then contain several matrices. I now want to add another point to for instance trail1
I can do that with Trail.trail1.a2rotated(i,:) = rotpoint'; the problem is that i have to do it in a loop where the trail number as well as the a2rotated changes to e.g. a3rot...
I tired to do it like that
name ="trail"+num2str(z)+".a2rotated"+"("+i+",:)";
name = convertStringsToChars(name);
Trail.(name) = rotpoint'
But that gives me the error: Invalid field name: 'trail1.a2rotated(1,:)'.
Does someone have a solution?
The name in between brackets after the dot must be the name of a field of the struct. Other indexing operations must be done separately:
Trail.("trail"+z).a2rotated(i,:)
But you might be better off making trail(z) an array instead of separate fields with a number in the name.

VSCode Extension: Get outline of function for custom outliner

I'm trying to create a custom outliner for VSCode (currently only for python), but I don't find measures to get the information I needed.
I like to get information in this manner this:
Array:
[0]
label: "foo"
type: "Function"
parameters: [...]
Range: [...]
innerDefinitions: [0]
[1]
label: "myclass"
type: "Class"
base_class: ""
Range: [...]
innerDefinitions:
[0]:
[...]
[1]:
[...]
Currently I try to get outline information via vscode.commands.executeCommand( 'vscode.XXX'
What I've tried:
Here is what commands I've tried and what result I received.
vscode.executeImplementationProvider
half usable: range of functionname. Other information is missing
vscode.executeHoverProvider
half usable: string of function head (including def keyword)
vscode.executeDefinitionProvider
half usable: range of complete function. Individual information must be "parsed out"
vscode.executeTypeDefinitionProvider
Never provided any result
vscode.executeDeclarationProvider
Never provided any result
vscode.executeDocumentSymbolProvider
Goes in a good direction. However
(1) Does only work on the whole document (not single function)
(2) Does only return first-level entities (i.e. class methods are not included in result)
Is there any API call I've overseen?
I wonder how the built-in outliner works, as it contains all-level information.
You need to use vscode.commands.executeCommand<vscode.Location[]>("vscode.executeDocumentSymbolProvider", uri, position)
This will give you the full outline of one file. There is no way to receive a partial outline.
Note: innerDefinitions are called children here.
Regarding the detail of the outline:
How detailed (and correct) an outline is going to be, depends on the implementation of the provider. Also, provider's information is no necessarily consistent among languages. This is very important to keep in mind!
At the moment (2021/03), the standard SymbolProvider for...
... Python will have a child for each parameter and local variable of a function. They will not be distinguishable
... C++ will contain no children for parameters. But it will have the parameter types in its name. (e.g. name of void foo(string p) will be foo(string): void.
As you can see, both act differently with their own quirks.
You could create and register a DocumentSymbolProvider yourself, that would return a level of detail you need (see VSCode Providers)
Also see: https://stackoverflow.com/a/66486297/6702598

RDF4J not filtering TreeModel in expected way

I have a TTL with something like
ex:isDataProperty rdf:type owl:DatatypeProperty .
ex:Article a owl:Class ;
owl:hasKey ( ex:isDataProperty ) .
And when I load the model with RDF4J (as a TreeModel) then try to filter to extract the properties annotated with haskey fails (just returns empty list result)
Some samples that return data:
val dataProperties = model.filter(null, RDF.TYPE, OWL.DATATYPEPROPERTY).subjects().asScala
val classes = model.filter(null, RDF.TYPE, OWL.CLASS).subjects().asScala
The sample I want, that doesn't return data:
val propertiesWithKeys = model.filter(null, RDF.PROPERTY, OWL.HASKEY).subjects().asScala
I have tried a few variations of the previous one using RDF.TYPE or RDF.Value. (instead of RDF.PROPERTY)
The thing you're after is any subject that has a owl:hasKey property, regardless of value. So both the subject and the object are wildcards, you just want to filter by property name. The way to do that is like this:
model.filter(null, OWL.HASKEY, null)
Now, furthermore you say that you want to know the properties that have been used as annotation using this owl:hasKey property. In your example, that would be ex:isDataProperty. Note that in your model, this is not the subject of the owl:hasKey relation - it's in the object values:
model.filter(null, OWL.HASKEY, null).objects()
To further complicate matters, the object values in your example are not simply single values. Instead, each class is annotated using a list of properties, so the object value is a list object (a.k.a. an RDF Collection). To process this list, there are some utility methods provided by the Models and RDFCollections classes.
For each of the objects you can do this to get the actual list of values:
RDFCollections.asValues(model, objectNode, new ArrayList<Value>())
(where objectNode is one of the values that .objects() returned)
Edit since objects() returns objects of type Value and RDFCollections expects a Resource, you'll either have to do a cast, or if you want to do all of this in a fluent way, you can use Models.objectResources instead. The whole thing then becomes:
Models.objectResources(model.filter(null, OWL.HASKEY, null))
.asScala.map(o => RDFCollections.asValues(model, o, new ArrayList[Value]()));
(I may have the Scala-specific bits of this wrong, but you get the gist hopefully)
For more information on how to work with the rdf4j Model API and with RDF Collections, see the rdf4j documentation.

Write a struct into a DICOM header

I created a private DICOM tag and I would like to know if it is possible to use this tag to store a struct in a DICOM file using dicomwrite (or alike), instead of creating a field inside the DICOM header for each struct field.
(Something like saving a Patient's name, but instead of using a char data, I would use double)
Here is an example:
headerdicom = dicominfo('Test.dcm');
a.a = 1; a.b = 2; a.c = 3;
headerdicom.Private_0011_10xx_Creator = a;
img = dicomread('Test.dcm');
dicomwrite(img, 'test_modif.dcm', 'ObjectType', 'MR Image Storage', 'WritePrivate', true, headerdicom)
Undefined function 'fieldnames' for input arguments of type 'double'.
Thank you all in advance,
Depending on what "struct" means, here are your options. As you want to use a private tag which means no application but yours will be able to interpret it, you can choose the solution which is technically most appropriate. Basically your question is "which Value Representation should I assign to my private attribute using the DICOM toolkit of my choice?":
Sequence:
There is a DICOM Value Representation "Sequence" (VR=SQ) which allows you to store a list of attributes of different types. This VR is closest to a struct. A sequence can contain an arbitrary number of items each of which has the same attributes in the same order. Each attribute can have its own VR, so if your struct contains different data types (like string, integer, float), this would be my recommendation
Multi-value attribute:
DICOM supports the concept of "Value Multiplicity". This means that a single attribute can contain multiple values which are separated by backslashes. As the VR is a property of the attribute, all values must have the same type. If I understand you correctly, you have a list of floating point numbers which could be encoded as an array of doubles in one field with VR=FD (=Floating Point Double): 0.001\0.003\1.234...
Most toolkits support an indexed access to the attributes.
"Blob":
You can use an attribute with VR=OB (Other Byte) which is also used for encoding pixel data. It can contain up to 4 GB of binary data. The length of the attribute tells you of how many bytes the attribute's value consists. If you just want to copy the memory from / to the struct, this would be the way to go, but obviously it is the weakest approach in terms of type-safety and correctness of encoding. You are going to lose built in methods of your DICOM toolkit that ensure these properties.
To add a private attribute, you have to
reserve a range for the attribute specifying an odd group number and a prefix (2 hex digits) for the element numbers. (e.g. group = 0x0011, Element = 0x10xx) reserves a range from (0x0011, 0x10xx) - (0x0011, 0x10ff). This is done by specifying a Private Creator DICOM tag which holds a manufacturer name. So I suspect that instead of
headerdicom.Private_0011_10xx_Creator = a;
it should read e.g.
headerdicom.Private_0011_10xx_Creator = "Gabs";
register your private tags in the private dictionary, most of the time by specifying the Private Creator, group, element and VR (one of the options above)
Not sure how this can be done in matlab.

Exporting the output of MATLAB's methodsview

MATLAB's methodsview tool is handy when exploring the API provided by external classes (Java, COM, etc.). Below is an example of how this function works:
myApp = actxserver('Excel.Application');
methodsview(myApp)
I want to keep the information in this window for future reference, by exporting it to a table, a cell array of strings, a .csv or another similar format, preferably without using external tools.
Some things I tried:
This window allows selecting one line at a time and doing "Ctrl+c Ctrl+v" on it, which results in a tab-separated text that looks like this:
Variant GetCustomListContents (handle, int32)
Such a strategy can work when there are only several methods, but not viable for (the usually-encountered) long lists.
I could not find a way to access the table data via the figure handle (w/o using external tools like findjobj or uiinspect), as findall(0,'Type','Figure') "do not see" the methodsview window/figure at all.
My MATLAB version is R2015a.
Fortunately, methodsview.m file is accessible and allows to get some insight on how the function works. Inside is the following comment:
%// Internal use only: option is optional and if present and equal to
%// 'noUI' this function returns methods information without displaying
%// the table. `
After some trial and error, I saw that the following works:
[titles,data] = methodsview(myApp,'noui');
... and returns two arrays of type java.lang.String[][].
From there I found a couple of ways to present the data in a meaningful way:
Table:
dataTable = cell2table(cell(data));
dataTable.Properties.VariableNames = matlab.lang.makeValidName(cell(titles));
Cell array:
dataCell = [cell(titles).'; cell(data)];
Important note: In the table case, the "Return Type" column title gets renamed to ReturnType, since table titles have to be valid MATLAB identifiers, as mentioned in the docs.