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 can i pass struct (with string) from unmanaged ? #238

Closed
Zeki-Gursoy opened this issue Oct 31, 2024 · 2 comments
Closed

How can i pass struct (with string) from unmanaged ? #238

Zeki-Gursoy opened this issue Oct 31, 2024 · 2 comments
Labels

Comments

@Zeki-Gursoy
Copy link

Zeki-Gursoy commented Oct 31, 2024

Hello.
I need pass UDT from VBA to c# dllexport function. But not show anything.

C# side:
[code]
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ClassLibrary1
{
public unsafe class Class1
{
[DllExport(CallingConvention.StdCall)]
public static void test(ref Record rec)
{

        MessageBox.Show(rec.Value + "");
    }


}

[ComVisible(true)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct Record
{
    [MarshalAs(UnmanagedType.LPStr)]
    public string Value;
}

}
[/code]

Excel VBA side (bas module):

`Type Record2
Name As String
Value As String
End Type

Private Declare PtrSafe Sub test Lib "C:\mypath\ClassLibrary1.dll" (ByRef rec2 As Record2)

Sub deneme()
Dim r As Record2

r.Value = "zeki"

test r

End Sub`

@3F
Copy link
Owner

3F commented Nov 2, 2024

Hello Zeki,

It's hard to tell how marshalling is going without debugging in your case when you're trying to refer it as an actual clr type.
For this case or such I recommend to use IntPtr because it exactly allows you to fully control the process step by step.

In your VBA script you can change the Declare signature to LongPtr same like I suggested here #189 (comment)
Note also you don't need unsafe context.

For IntPtr control your structure either through PtrToStructure() or use Conari like:

[DllExport(CallingConvention.StdCall)]
public static void test(IntPtr ptr)
{
    ptr.Native().f<CharPtr>("s")._.s // (CharPtr)"zeki"
}

If strong typing is required,

public struct Record { public string Value; }
//...
using NativeStruct<Record> nst = new(ptr); // nst.Data.Value == "zeki"

or almost the same but generated at runtime (i.e. without declaring the actual at compile time)

ptr.Native().f<CharPtr>("Value").build(out dynamic record);
//dynamic record = ptr.Native().f<CharPtr>("Value").Struct.Access;

Here you can find updated tests for strings, arrays, and structures:
https://github.com/3F/DllExport/blob/master/src/DllExport/assets/NetfxAsset/Basic.cs

@Zeki-Gursoy
Copy link
Author

Thank you for reply.

Regards,

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