Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to properly use the "NativeStruct" from current Conari Version? #21

Open
CodingMadness opened this issue Jan 13, 2022 · 19 comments
Open
Labels

Comments

@CodingMadness
Copy link

In your video: https://www.youtube.com/watch?v=QXMj9-8XJnY

you used the obsolete-way with UnmanagedStructure, now you suggest using the NativeStruct way, can u maybe give me a short example of how to make use of those properly, to be able to call it from C++/Delphi?

Because, when i compile the following code:
image

I get the error you can see in the "Error-dialogbox" below in the screenshot.

How to adapt to that new change you have done for Conari?

Much thanks!

@CodingMadness
Copy link
Author

Sry, my bad, the code issue relied on smth else... forget this ticket!

@3F
Copy link
Owner

3F commented Jan 13, 2022

You're right, UnmanagedStructure is marked as obsolete and planned to be removed in future major releases.

Please note, modern NativeStruct provides several ways https://github.com/3F/Conari/wiki/Quick-start#conari-types

For example, you don't need a CLR types declarations at all if this is a fully automatic way, in your example,

NativeStruct.Make.t<CharPtr, int>("a", "b").Struct;

Also do not need a manual marshaling (Marshal.PtrToString...) everything is automated.

This project unfortunately does not provide some good documentations today, but please first try my tests as an example:

Let me know if you still have some problems, I'll try to look into later.

@3F
Copy link
Owner

3F commented Jan 13, 2022

Sry, my bad, the code issue relied on smth else... forget this ticket!

I see :) Just close it yourself if it's ok

@CodingMadness
Copy link
Author

CodingMadness commented Jan 13, 2022

You're right, UnmanagedStructure is marked as obsolete and planned to be removed in future major releases.

Please note, modern NativeStruct provides several ways https://github.com/3F/Conari/wiki/Quick-start#conari-types

For example, you don't need a CLR types declarations at all if this is a fully automatic way, in your example,

NativeStruct.Make.t<CharPtr, int>("a", "b").Struct;

Also do not need a manual marshaling (Marshal.PtrToString...) everything is automated.

This project unfortunately does not provide some good documentations today, but please first try my tests as an example:

Let me know if you still have some problems, I'll try to look into later.

Thanks so far for that example!

My only question now is: by using .NET 6, i am using "record struct" feature, to test this out, but since i have a feeling that it wont work like this, i created a struct-wrapper around that record-struct, like this:

image

And would this code I have written to allocate unmanaged.memory for that wrapper be okay?

have a look:

image

Thanks in advanced!

@3F
Copy link
Owner

3F commented Jan 13, 2022

but since i have a feeling that it wont work like this

Why? Did you try it?

~
NativeStruct<SomeRecordStructDef> ns = new(instance);

record struct (record ie. records) just tells the compiler to override some default operators and implements some extra logic in basic struct type for new features available in modern C# and so on.

So I don't see the problem as long as it's marked as LayoutKind.Sequential.
Or use Conari's chains to construct any fields at runtime.

If you need some wrapping in any case,

Well, you can implement some cloning of the available fields into some new type like

SomeRecordStruct srs = ...
using NativeStruct<Wrapper> ns = new(srs.Clone());

Or note, NativeStruct also provides accessing to IntPtr if you want to wrap it inside somewhere somehow

NativeStruct<Wrapper> ns = ...
IntPtr ptr = ns;

etc.

@3F 3F added the question label Jan 13, 2022
@3F
Copy link
Owner

3F commented Jan 13, 2022

by the way, actually LayoutKind.Sequential limitation is not really ... FYI, https://twitter.com/github3F/status/1317526371921502210

@CodingMadness
Copy link
Author

CodingMadness commented Jan 13, 2022

sadly tho, my code based on ur suggestion compiles fine BUT then this:

image

?
here code:

image

This is my converter-record:

image

@3F
Copy link
Owner

3F commented Jan 13, 2022

@Shpendicus

The "empty" export table does not related to NativeStruct use at all. This is not related even for .NET 6 limitation (I hope).

As I said here 3F/DllExport#197 (comment)

Make sure you're looking at correct assembly (x64 or x86 folder if you're using both arch)

Or, please open new issue on DllExport project as a bug since empty export directory. I'll investigate it later. Only please follow report steps and provide all minimal information about settings etc. Thanks.

@CodingMadness
Copy link
Author

CodingMadness commented Jan 14, 2022

image

This is entire function to call the "public static int AllocRecord() {return 10 + 35};" function from .NET 6 and sadly, the equivalent call in Delphi, SEES my exported functions, i get a valid pointer from GetProcAdress(...) BUT when i call it, it shows;:

"External Exception: 0434352"

do you have maybe a clue how this possible? Again, both LoadLib and GetProcAdr do work! and return seeminlgy valid pointers, but then that exception raises for some reason. really strange.

@3F
Copy link
Owner

3F commented Jan 14, 2022

the equivalent call in Delphi, SEES my exported functions

As I see, the "empty" problem is fixed now?

"External Exception: 0434352"
do you have maybe a clue how this possible?

Depends on your configuration. Copy everything from DllExport's Data tab in GUI

Did you try Use our IL Assembler + Rebase System Object ?

@CodingMadness
Copy link
Author

the equivalent call in Delphi, SEES my exported functions

As I see, the "empty" problem is fixed now?

"External Exception: 0434352"
do you have maybe a clue how this possible?

Depends on your configuration. Copy everything from DllExport's Data tab in GUI

Did you try Use our IL Assembler + Rebase System Object ?

sry mate but how u mean "Copy everything from DllExport's Data tab in GUI"

Did you try Use our IL Assembler + Rebase System Object ?
And what u mean by this? I used ur config tool with the GUI, and i did exactly as u did , idk, for the Conari version I m not sure what to use else , i only copied the config from ur GUI in the yt video. :/ not sure what to change.

@3F
Copy link
Owner

3F commented Jan 14, 2022

Modern 1.7+

  1. Check the mentioned options on the right
  2. [Data] - You can find it after end of project list as you can see

for the Conari version I m not sure what to use else

For Conari everything is fine :)

@CodingMadness
Copy link
Author

image

I really, did the exact same settings u took there in the image above. but i get the above error :/

maybe im just a jerk xD

@3F
Copy link
Owner

3F commented Jan 14, 2022

About full sign, here 3F/coreclr#6

maybe im just a jerk xD

Too many features, dependencies, limitations, and a bit documentation.
I mean not everything is so bad :) Feel free to ask, change via PR, or suggest something, and we'll find solution together.

@CodingMadness
Copy link
Author

Mate, what im asking now may sound bit much, i admit, but still ; would you mind, adding me on Discord, and use "Share Screen" and watch me how I do the stuff, and then show me maybe, what i am doing wrong and correct me, (am using .net 6; VS 2022)

i would pay u 3€+ per month :) so from 7 to 10€, if u only help me once with this, its so important for me, getting this done in time since i actually am writing for a company a software module, for my university-internship and i wanted to drastically get this work, managing writing code in new .NET 6 and call it from anywhere unmanaged, like Delphi/FPC/C++ etc..

@CodingMadness
Copy link
Author

@3F forget what i wrote (i will increase the payment to 10€ anyways, dw!) i made it work, bro :-D finally, i forgot to check in the Configurator in your image above, the option: "-nan(ind)" and then it worked fine :)

The only thing now, i wonder: when i want to return string, or Datetime, as I can see for now, i get a valid pointer back from my function but when i cast my funcPtr to the proper and correct function definition:
image

I wonder, why he cant execute that, Free pascal-Compiler executes with code "217", and aborts abruptly. What could cause this?

@3F
Copy link
Owner

3F commented Jan 15, 2022

i would pay u 3€+ per month :) so from 7 to 10€, if u only help me once with this, its so important for me,

:) I appreciate any support to me, however, something like this always reminds me of an attempt to buy me or my time in order to solve some tasks or even complete some work. But it costs a lot more.

i made it work, bro :-D finally

I am glad to hear this!

I wonder, why he cant execute that, Free pascal-Compiler executes with code "217", and aborts abruptly. What could cause this?

For today's DllExport 1.7.4 the .NET 6 support is incomplete and more likely(*) will cause some related errors as it was mentioned earlier in DllExport repo.
(* for some cases it may indeed already be ok, for example, like from my yt video where basic pAdd functions etc.)

Try netstadard2.0, if it will work for the same code then this is it. If no, then something with marshaling that can be fixed in your code.

@CodingMadness
Copy link
Author

:) I appreciate any support to me, however, something like this always reminds me of an attempt to buy me or my time in order to solve some tasks or even complete some work. But it costs a lot more.

Sry for that, that was the reason I regret formulating my sentence like this, I thought it actually more as a little motivation for a quick help ^^ (sry for that..)

for the rest, well i think i will write the entire App for now in Delphi, its to complicated like this :D

@3F
Copy link
Owner

3F commented Jan 15, 2022

for the rest, well i think i will write the entire App for now in Delphi, its to complicated like this :D

Why not temporarily decrease TFM to netstandard2.0 until fixes? or btw netfx-based such as net48
I mean changing some parts of the existing source code (just to be compatible for TFM) is a bit faster than fully rewriting it. Isn't it?

For better you can simply use conditional compilation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants