Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / July 2005

Tip: Looking for answers? Try searching our database.

__declspec(dllexport) to return char but errors in VB6

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jason W - 25 Jul 2005 20:10 GMT
I have a C# class that I wan't to be able to use in VB6 and VBA
applications. To do this I was trying to use a mixed managed VC++ dll and
export a function. Doing this I get an error "The memory could not be
"read"".

Can any one explain what I am doing wrong?

This is my Code.

.CPP

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Collections;
using namespace WdCadTmInfo;
#define WDINFO_LINKAGE __declspec(dllexport)
#include "PlotAccounting-C.h"

__gc class ManagedObjects{
public:
};

BOOL APIENTRY
  DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{

  return TRUE;
}

extern "C"{
WDINFO_LINKAGE char* getWdInfo(char* Param){

 wdCadTeamInfo* tmpInfo = new wdCadTeamInfo();

 IntPtr ptr = Marshal::StringToHGlobalAnsi(tmpInfo->GetWdCadTmInfo(Param));
 char __nogc* pStr = static_cast<char*>(ptr.ToPointer());

 Marshal::FreeHGlobal(ptr);

 return pStr;

}
}

.H

#ifndef WDINFO_LINKAGE
#define WDINFO_LINKAGE __declspec(dllimport)
#endif
extern "C"{
  WDINFO_LINKAGE char* getWdInfo(char* Param);
}
Mattias Sjögren - 26 Jul 2005 09:12 GMT
>Can any one explain what I am doing wrong?

The pointer you're returning is invalid since you just freed the
memory it points to.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jason W - 26 Jul 2005 13:36 GMT
Thank you for your reply!

I was switching code around and placed the FreeHGlobal in the wrong place
for my post.

changing it to this

WDINFO_LINKAGE char* getWdInfo(char* Param){

 IntPtr ptr = Marshal::StringToHGlobalAnsi(S"Testing return");
 char __nogc* pStr = static_cast<char*>(ptr.ToPointer());

 return pStr;

 Marshal::FreeHGlobal(ptr);
}

doesn't give me the error but doesn't return anything back.

Thanks in advance.

Jason
   Wood

> >Can any one explain what I am doing wrong?
>
> The pointer you're returning is invalid since you just freed the
> memory it points to.
>
> Mattias
Mattias Sjögren - 27 Jul 2005 16:19 GMT
>WDINFO_LINKAGE char* getWdInfo(char* Param){
>
[quoted text clipped - 7 lines]
>
>doesn't give me the error but doesn't return anything back.

Now the FreeHGlobal call is dead code that will never execute instead,
the compiler should warn you about that.

You either have to switch to a model where the caller passes in a
buffer to be filled, specify that the caller must free the memory with
LocalFree, or provide another function that frees the memory later.
You can't both return the pointer and free the memory it points to in
the same function.

As to why you don't get anything on the VB side, I would have to see
the callng code to tell.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jason W - 27 Jul 2005 21:14 GMT
I didn't think I was doing it correct. I've been reading and found what I
believe to be the correct way to do this but VB6 still errors.

I can get it to work in C# but that isn't the language I'm looking for.
Am I making since about what I'm asking for?

<C# Code>
[DllImport(@"PlotAccounting-C.dll")]
static extern long getWdInfo(
string param,
System.Text.StringBuilder returnParm
);

[STAThread]
static void Main(string[] args)
{
System.Text.StringBuilder returnIt = new
System.Text.StringBuilder(500,500);
Console.WriteLine(getWdInfo("Testing", returnIt).ToString());
Console.WriteLine(returnIt.ToString());
}

<VB6 Code>
Public Declare Function getWdInfo Lib "PlotAccounting-C.dll" (ByVal param As
String, paramOut As String) As Long
Dim testing As String
testing = "Not Set"
MsgBox getWdInfo("PlotAccounting", testing)

<PlotAccount-c.cpp>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#using <mscorlib.dll>
#define WDINFO_LINKAGE __declspec(dllexport)
#include "PlotAccounting-C.h"
#include "shlwapi.h"

__gc class ManagedObjects{
public:
};

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
  return TRUE;
}

extern "C"{
WDINFO_LINKAGE void getWdInfo(char* Param, LPTSTR returnParm){
 char __nogc* pStr =
static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGloba
lAnsi(S"Return Value").ToPointer());
 StrCpy(returnParm,pStr);

System::Runtime::InteropServices::Marshal::FreeCoTaskMem(System::IntPtr((voi
d*)pStr));
 return;

}
}

<PlotAccounting-c.h>
#ifndef WDINFO_LINKAGE
#define WDINFO_LINKAGE __declspec(dllimport)
#endif

extern "C"{
  WDINFO_LINKAGE void getWdInfo(char* Param, LPTSTR returnKey);
}

> >WDINFO_LINKAGE char* getWdInfo(char* Param){
> >
[quoted text clipped - 21 lines]
>
> Mattias
Jason W - 27 Jul 2005 21:29 GMT
I've found what I'm doing wrong. After reading a little feather in to StrCpy
I foud that I'm causing a buffer overrun by coping more than the origial
has. I need to test for the lenght before I copy the data.

Thanks for all your help Mattias!

Jason
   Wood

> I didn't think I was doing it correct. I've been reading and found what I
> believe to be the correct way to do this but VB6 still errors.
[quoted text clipped - 45 lines]
>  WDINFO_LINKAGE void getWdInfo(char* Param, LPTSTR returnParm){
>   char __nogc* pStr =

static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGloba
> lAnsi(S"Return Value").ToPointer());
>   StrCpy(returnParm,pStr);

System::Runtime::InteropServices::Marshal::FreeCoTaskMem(System::IntPtr((voi
> d*)pStr));
>   return;
[quoted text clipped - 36 lines]
> >
> > Mattias

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.