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 / .NET Framework / Interop / December 2004

Tip: Looking for answers? Try searching our database.

Memory Allication (Managed VC++ to Unmanaged DLL)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Weston Fryatt - 27 Dec 2004 21:20 GMT
Simple question on memory allocation.

I have a "Unmanaged" Client DLL that I'm creating a Managed wrapper to be
used in Visual Basic .Net and C#..

Current in on the client side of the application, There are points where I
need to allocate a "client side" memory buffer to marshall data into from
the server side. Normally in VC++ 7.1 (unmanaged) I would normally just
malloc the memory that I needed:

   Example:

       typedef unsigned char UBYTE;
       typedef unsigned long STATUS;

       STATUS Status = EC_OK;
       UBYTE *pData = NULL;
       DWORD dwDataSize = 0;

       try
           {
           Status = GetBufferSize(dwDataSize);
           if (Status)
               {
               pData = (UBYTE *)malloc(dwDataSize);
               if (pData)
                   {
                   Status = GetServerSideData(dwDataSize, pData);
                   if (Status)
                       {
                       // Do something with pData
                       }
                   free(pData);
                   pData = NULL;
                   }
               }
           }
       catch(...)
           {
           if (pData)
               free(pData);
           }

Now... I need to do the same thing in my client wrapper but in a "managed"
way.. I've tried so far using new, and malloc in a managed VC++ DLL .. But
just doesn't work when the function is called in a VB.Net app...  I've also
tried to use the keyword __pin to pin down the memory, But still doesn't
work..

So what am I missing?? How do I allocate a memory block in a managed VC++
DLL and pass that memory pointer over to an unmanaged DLL??

Thanks,
Weston Fryatt
Mattias Sj?gren - 27 Dec 2004 23:24 GMT
Weston,

>Now... I need to do the same thing in my client wrapper but in a "managed"
>way.. I've tried so far using new, and malloc in a managed VC++ DLL .. But
>just doesn't work when the function is called in a VB.Net app...  I've also
>tried to use the keyword __pin to pin down the memory, But still doesn't
>work..

In what way is it failing? I assume the code compiles since you can
call it from VB.

Mattias

Signature

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

Weston Fryatt - 28 Dec 2004 00:05 GMT
Yes the code compiles fine on both side (VB.Net and Managed VC++ DLL). No
errors or warnings.

On the VB.Net side I get an:

   An unhandled exception of type 'System.NullReferenceException' occurred
in cdmsclientdotnet.dll
   Additional information: Object reference not set to an instance of an
object.

When executing this on the Managed VC++ side:

    pDataPtr = (UBYTE *)new char[dwDataSize];

Here is a bigger code fragment:

Managed VC++ DLL:

namespace CDMSClient_SQL
   {
   [DllImport("CDMSClient.dll", EntryPoint = "SQLGetRows", CharSet = Ansi)]
       STATUS SQLGetRows(const Int32 RowCount, const Int32 DataSize, UBYTE
*Data, String *Columns, String *From, String *Where, String *OrderBy);

   [DllImport("CDMSClient.dll", EntryPoint = "SQLGetRowInfo", CharSet =
Ansi)]
       STATUS SQLGetRowInfo(Int32 &RowCount, Int32 &ColumnCount, Int32
&DataSize, String *Columns, String *From, String *Where);
   }

Array *CCDMSClientInterface::SQLGetRows(const Int32 MaxRows, String
*Columns, String *From, String *Where, String *OrderBy)
   {
   STATUS Status = EC_OK;
   Int32 dwRowCount = 0;
   Int32 dwColumnCount = 0;
   Int32 dwDataSize = 0;
   Array *Data = NULL;
   UBYTE __pin *pDataPtr = NULL;

   Status = CDMSClient_SQL::SQLGetRowInfo(dwRowCount, dwColumnCount,
dwDataSize, Columns, From, Where);
   if (Status == EC_OK)
       {
       pDataPtr = (UBYTE *)new char[dwDataSize];    // <--- This is the
line that fails in the Managed VC++ Side
       Status = CDMSClient_SQL::SQLGetRows(dwRowCount, dwDataSize,
pDataPtr, "*", "CDMS_Config", "", "");
       if (Status == EC_OK)
           Data = Convert_CDBArray_2_Object(pDataPtr);
       }

   return (Data);
   }

VB.Net Side of code:

Imports ClientInterface = CDMSClientDotNet.CCDMSClientInterface

Module Module1

   Sub Main()
       Dim ci As ClientInterface = New ClientInterface
       Dim Data As Array
       Dim Status As Int32

       Status = ci.SetApplicationID("43C1F2F1-CB68-4B89-A8C8-5E0C42CE4866")
       If Status = 1 Then
           Status = ci.SetDomain("Primary")
           If Status = 1 Then
               Status = ci.CreateServerContext()
               If Status = 1 Then
                   Status = ci.Login("admin", "optical")
                   If Status = 1 Then
                       Console.WriteLine("Logged In!")

                       Data = ci.SQLGetRows(1000, "*", "CDMS_Config", "",
"")        // <---This is the line that fails in the VB.Net side

                       ci.Logout()
                   Else
                       Console.WriteLine("Failed to Login!")
                   End If
                   ci.DeleteServerContext()
               Else
                   Console.WriteLine("Failed to Create Server Context!")
               End If
           Else
               Console.WriteLine("Failed to Set Domain!")
           End If
       Else
           Console.WriteLine("Failed to Set ApplicationID!")
       End If
   End Sub

End Module

I have many functions that pass data from the server side to the client side
via a memory buffer.  This data in the memory buffer is parsed and put back
into a dynamic array (Custom C++ class called a CDBArray).  The first
function that I'm trying to get to work, fetches a database table from the
server side and marshalls it back over to the client side. The Server and
Client is using RPC to marshall data back and forth. (Just a side note, The
client side can not access the database directly via ODBC or anything else.
It must go thought my client dll.  This is done for security reason to keep
the client side locked down.)

Any ideas or suggestion are more than welcomed!!

Thanks Again!
Weston Fryatt

> Weston,
>
[quoted text clipped - 8 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.