Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Marshaling to LPSTR *

Status
Not open for further replies.

jmcpher

Programmer
Jun 4, 2001
84
US
I am trying to get this function:

DllExport HRESULT WINAPI readrtf (LPSTR lpProfileName, LPSTR lpMsgIDSrc, LPSTR lpStoreIDSrc, LPSTR *lpRTF)

to run from my C# code. I am using this statement:

[DllImport("mapirtf.dll")]
private static extern int readrtf (string ProfileName, string SrcMsgID, string SrcStoreID, [MarshalAs(UnmanagedType.LPStr)] ref StringBuilder MsgRTF);

to import the function. I then try to access it as such:

StringBuilder ans = new StringBuilder(100);

readrtf((string) ((MAPI.Session) my_message.Session).Name, (string) my_message.ID, (string) my_message.StoreID, ref ans)

return ans.ToString();

But the return value is empty. I have tried not using ref on the StringBuilder but I get an error saying that an object reference has not been set. Any ideas on how to properly marshal the StringBuilder in this case?

"Programming is like sex, one mistake and you have to support it forever."

John

johnmc@mvmills.com
 
jmcpher,

Forgive me if I may be way off base (haven't dealt with API in QUITE a while ;)), but when you are actually using the function

readrtf((string) ((MAPI.Session) my_message.Session).Name, (string) my_message.ID, (string) my_message.StoreID, ref ans)

you may perhaps want to try using the StringBuilder's .ToString() method like so:

readrtf((string) ((MAPI.Session) my_message.Session).Name, (string) my_message.ID, (string) my_message.StoreID, ref ans.ToString())

The reason (right of the top of my head) for this would be because "ref ans" is setting a reference to the StringBuilder object and not it's contents (and as you are using an LPSTR, you would be wanting to point to the string itself). I have had a couple issues with the StringBuilder object and how I am accessing it's contents and it may be that you're having the same issue here.

Just a <kinda> educated guess - Hope it helps :)

-----------------------------------------------
&quot;The night sky over the planet Krikkit is the least interesting sight in the entire universe.&quot;
-Hitch Hiker's Guide To The Galaxy
 
That doesn't work becuase ans.ToString() returns a string, and I have to pass a StringBuilder into the function because I want to get the text back. If I pass a string, the Marshal won't copy the value back from the call.

&quot;Programming is like sex, one mistake and you have to support it forever.&quot;

John

johnmc@mvmills.com
 
OK, figured out the problem. Turns out the code that I am calling using strlen() to figure out how much space it has to read in to. So, since I am creating an empty StringBuilder, it thought there was no space and so I was getting an empty string back. Now I use ans.Append(' ', size) to create a long string.

I am having another problem though. When I make the call, if the value of size is greater than 16, I get an error telling me the capacity exceeds maximum capacity. I have used the debugger to see that maximum capacity is 2147483647 before the call, and is always 16 after the call. Any ideas about whats happening here?

&quot;Programming is like sex, one mistake and you have to support it forever.&quot;

John

johnmc@mvmills.com
 
Although I have no idea why my StringBuilder object was getting trashed, I managed to fix the problem by editing the unmanaged code to take a LPSTR instead of a LPSTR *. Once I did this, it worked wonderfully.

&quot;Programming is like sex, one mistake and you have to support it forever.&quot;

John

johnmc@mvmills.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top