Passing a structure having strings to C++

Uzamčený Passing a structure having strings to C++

  • 18. července 2012 19:26
     
      Obsahuje kód

    Hi all,

    I am trying to pass a structure that contains a string to C++. I am having trouble in doing so. There seems to be a read/write memory error when I execute the code. The following is the code listing

    C++

    ============
    | Driver.h |
    ============
    
    struct FluidDescription
    {
    	char *componentName;
    
    	int phaseCode;
    };
    
    struct InputData
    {
    	FluidDescription ccmp;
    };
    
    #if defined (EXPORT)
    #define DLL_EXPORT __declspec(dllexport)
    
    #else
    #define DLL_EXPORT __declspec(dllimport)
    #endif
    
    extern "C"
    {
    	int DLL_EXPORT WriteInputFile(InputData *input);
    }
    
    ==============
    | Driver.cpp |
    ==============
    
    #include <iostream>
    #include "Driver.h"
    
    using namespace std;
    
    int WriteInputFile(InputData *input)
    {
    	cout << input->ccmp.phaseCode << endl;
    	cout << input->ccmp.componentName << endl;
    
    	return 0;
    }

    VB.net

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        <DllImport("StructPassTest.dll", CallingConvention:=CallingConvention.Cdecl)> _
        Private Shared Function WriteInputFile(ByRef input As InputData) As Integer
    
        End Function
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure InputData
            Public ccmp As FluidDescription
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure FluidDescription
            Public phaseCode As Integer
            Public componentName As String
        End Structure
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim input As New InputData
            Dim rc As Integer
            
            input.ccmp.componentName = "Test"
            input.ccmp.phaseCode = 1
            rc = WriteInputFile(input)
            MsgBox(rc)
    
            
        End Sub
    End Class

    The program fails when it enters the function WriteInputFile. On searching the internet, i figured that I had to use the Marshaling feature to convert the string within the structure to unmanaged type.

    In order to do that it was suggested IntPtr be used. So I changed the struct FluidDescription as follows

    <StructLayout(LayoutKind.Sequential)> _
        Public Structure FluidDescription
            Public phaseCode As Integer
            Public componentName As IntPtr
        End Structure

    and I tried my best to somehow convert the string into a IntPtr and had no luck in doing so.

    I would appreciate if someone can post a snippet as to how I can populate the variable componentName with a value and pass it to C++

    Should I also convert the structure InputData to a IntPtr before passing it to the function WriteInputFile?

    Thanks in advance,

    Kaushik



    • Změněný typ iamreal 18. července 2012 19:37
    •  

Všechny reakce

  • 18. července 2012 19:33
     
     Odpovědět Obsahuje kód

    First step is correcting the order of the fields in the structure FluidDescription.

    In addition, try this:

    <MarshalAs(UnmanagedType.LPStr)> Public componentName As String

    BTW, there's a specialized Interop forum: http://social.msdn.microsoft.com/Forums/en-US/vbinterop/threads

    Please change the thread type from discussion to question.


    Armin

  • 18. července 2012 20:03
     
      Obsahuje kód

    Hi Armin,

    Changing the order solved the problem for me. I didn't have to use the

    <MarshalAs(UnmanagedType.LPStr)> Public componentName As String

    in my structure.

    I am curious as to why I was able to get it to work without using IntPtr that some of the forums were recommending?

    -Kaushik

  • 19. července 2012 10:00
     
     

    Hi Iamreal,

    please check this link MarshalAsAttribute Class:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute(v=vs.100).aspx


    No code, No fact.

  • 19. července 2012 14:05
     
     

    I am curious as to why I was able to get it to work without using IntPtr that some of the forums were recommending?

    Because you're "da maaaan"! Oh, or maybe "da womaaan". ;-)


    Armin