Hydra - passing structs from delphi host to .NET plugin

(Frederic Vancraeyveldt) #1

Is the docomentation in https://docs.hydra4.com/HowTos/PassingInterfacesBetweenHostAndPlugins/
up to date.
I am using hydra 6.1.97

and define my structures as
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TArticleInfoItem
{
// input fields (delphi application -> WWKS2 lib)
[MarshalAs(UnmanagedType.BStr)]
public string cnk;
[MarshalAs(UnmanagedType.BStr)]
public string name;
[MarshalAs(UnmanagedType.BStr)]
public string dosageinfo;
[MarshalAs(UnmanagedType.BStr)]
public string packagingunit;
public int extra;
}

and

TArticleInfoItem=record
// input fields (delphi application -> WWKS2 lib)
cnk:widestring;
name:widestring;
dosageinfo:widestring;
packagingunit:widestring;
extra:integer;
end;

however hydra functions like
public interface IWWKS2VendingMachinePluginFeedback : IHYCrossPlatformInterface
{
bool askArticlePriceInfo(string cnk, out TArticlePriceInfoItem item);

do not fill in the fields correctly.
Currently it looks like only the first half of the strings are copied.
Zero length strings are also null in the receiving .NET plugin.

Does records/structures communication work? If so, how?

0 Likes

(antonk) #2

Hello

How the askArticlePriceInfo method is defined on the Delphi side?

Actually please create a testcase app: a simple .NET plugin and a Delphi host app, just covering this one method and structure type and demonstrating the issues you have.

Thanks in advance

0 Likes

(Frederic Vancraeyveldt) #3

FYI: The delphi record is in the post, if I have some time I’ll make a test application

0 Likes

(Frederic Vancraeyveldt) #4

Hi,

Attached is a sample that fails.
Callback method 1 fails with this code.

However, when I changed the struct it was callback method 2 that failed.
A big issue which I reported earlier also is the fact that the generated code does not compile because it is missing the structures

testhydra.zip (4.8 MB)

0 Likes

(antonk) #5

Hello

Thanks for the testcase.

In this code:

     [Guid("C6F6B410-D905-4DEE-AFBF-1ADE6AF7632F")]
      public interface ITestHydraPluginFeedback : IHYCrossPlatformInterface
      {
        void logMessage(int sev, string msg);
        bool notifyData1(TSampleRecord data);
        bool notifyData2(out TSampleRecord data);
        bool notifyData3(ref TSampleRecord data);
      }

you have to change the second method definition to

        bool notifyData1(ref TSampleRecord data);

After this change your testcase seems to work properly.

0 Likes

(Frederic Vancraeyveldt) #6
  1. Could it be that there is something more fundamentally wrong?
    I have other code where ref crashes
    Some code only passes half of the string (first half of the characters)

  2. In any case I assume you want out also to work?

  3. At present no code is generated for structures, will you be adding this functionality?
    At present the generated delphi code DOES NOT COMPILE when structures are in the interface!

0 Likes

(antonk) #7

Main issue is that documentation should have mentioned that structures are a very low-level approach and should only be used in case of performance issues. More recommended way of work is to use/pass interfaces, not directly in-memory structures. Actually Hydra tools and approaches were designed for interfaces use, not structures.

Performance comes at the cost of the issues you see like manually-written structures code and properly defined methods (tbh I am not sure if out modifier will work with structures). Otherwise you’ll see hardly-to-catch issues.

IOW it should be not

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TArticleInfoItem
...

It should be

public interface IArticleInfoItem: IHYCrossPlatformInterface
...

Yes. It is expected that if you are going to use low-level stuff then you’ll also write the code required for this. Anyway Importer won’t be able to guarantee that the generated code is correct.

0 Likes