digitalmars.D.learn - De-Referencing A Pointer
- Rory Starkweather (31/31) Mar 20 2006 Still working on a VB to D DLL interface. I want to pass a string to a D
- Oskar Linde (6/12) Mar 21 2006 a char* cStr is converted to char[] by
- Regan Heath (4/19) Mar 21 2006 and you can get a dchar with std.utf.toUTF32().
- Regan Heath (10/33) Mar 21 2006 Oops, I should read the whole post before replying. Any character litera...
- Rory Starkweather (3/9) Mar 21 2006 Thanks for the help. I'm still not sure how to get VB to send a dchar, b...
- James Dunne (23/39) Mar 21 2006 Actually you want to use wchar* at the D end from VB. VB sends
- NoBoDy (9/48) Mar 21 2006 VB6 internally stores strings in UNICODE.
- James Dunne (12/76) Mar 21 2006 Thanks! That helps a lot for me as well. So then am I still correct in...
- John C (7/86) Mar 21 2006 VB strings are equivalent to COM's BSTR (which is wchar*), so you should...
- Rory Starkweather (4/12) Mar 21 2006 Now that I hadn't seen before. If I can get it to work, it will solve a ...
- Rory Starkweather (1/1) Mar 21 2006 How do I join this newsgroupd if that is what this is? What do I use for...
- Lars Ivar Igesund (8/10) Mar 21 2006 You use a NNTP-client ;) Most modern email-readers have one. Windows-use...
- Rory Starkweather (1/1) Mar 21 2006 Thanks. It was as easy as you said.
- James Dunne (17/81) Mar 21 2006 Correct me on this if I am wrong:
- xs0 (10/19) Mar 21 2006 Well, since you asked - it's not glyphs, but characters :)
- Rory Starkweather (61/74) Mar 21 2006 I may be running into that now. I decided to forget about the dchar issu...
- James Dunne (17/124) Mar 21 2006 I think we've discovered in another reply thread that the source of the
- Rory Starkweather (8/24) Mar 21 2006 StrPtr() call? You're just saying that its unfortunate that VB doesn't...
- Rory Starkweather (63/85) Mar 21 2006 I'm totally lost now. The DLL version didn't like the wchar* types and
- James Dunne (8/116) Mar 21 2006 As much as I'd love to help you out, I'm also hopelessly lost. Can you
- James Dunne (44/53) Mar 22 2006 The working code is attached with a sample Excel spreadsheet with
- Derek Parnell (9/36) Mar 23 2006 The foreach() has a mode of operation that automatically converts UTF
- James Dunne (11/57) Mar 23 2006 I understand that, I just didn't know the hidden foreach magic.
- Rory Starkweather (26/26) Mar 23 2006 I guess I would like to ask why I shouldn't do this at the same time I...
- Derek Parnell (22/54) Mar 23 2006 Yes it will, though it should be coded ...
- Oskar Linde (12/15) Mar 24 2006 That is not correct. The index returned is an index into the char[] arra...
- Rory Starkweather (15/38) Mar 24 2006 ay,
- Oskar Linde (12/46) Mar 24 2006 No, the c is a suffix to the string literal, defining it as a char[].
- Rory Starkweather (8/19) Mar 24 2006 =20
- Derek Parnell (6/23) Mar 24 2006 Thanks. It didn't used to be this way, I believe.
- Rory Starkweather (6/64) Mar 24 2006 Good point. Thanks for mentioning it.I hadn't really considered that.
- David L. Davis (7/7) Mar 21 2006 Rory, I've put together some code that I got to work, you can download i...
- tjohnson at prtsoftware . com (3/10) Mar 22 2006 Thanks. I was going to ask for this.
Still working on a VB to D DLL interface. I want to pass a string to a D function. The only way I have been able to do it without errors is ByRef on the VB end, as expected, to a char* on the D end. However, I want to use the 'find' function on the string. 'find' requires a char[] and a dchar as inputs. I haven't been able to figure out how to de-reference the pointer for the char[] and I don't know how to produce a dchar. Here's the code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findChar(char* searchString) //int findChar(char[] searchString, dchar searchChar) { int iPointer = 0; char[] eChar = "e"; char[] anotherString; anotherString = *searchString; //<- Here's the problem iPointer = find(anotherString, eChar); // iPointer = find(*searchString, eChar); // iPointer = find(&searchString, eChar); return (iPointer); } } The error message is "Cannot explicitly convert expression (*(searchString)) of type char* to char[]. If I take out the '*' I get about the same thing. The other problem is the dchar. What can I pass to the function that it will think is a dchar? Is there any documentation on this kind of thing? I haven't had much luck interpreting the language specification.
Mar 20 2006
Rory Starkweather skrev:Still working on a VB to D DLL interface. I want to pass a string to a D function. The only way I have been able to do it without errors is ByRef on the VB end, as expected, to a char* on the D end. However, I want to use the 'find' function on the string. 'find' requires a char[] and a dchar as inputs. I I haven't been able to figure out how to de-reference the pointer for the char[] and I don't know how to produce a dchar.a char* cStr is converted to char[] by cStr[0..std.c.string.strlen(cStr)] or std.string.toString(cStr) /Oskar
Mar 21 2006
On Tue, 21 Mar 2006 09:00:15 +0100, Oskar Linde <oskar.lindeREM OVEgmail.com> wrote:Rory Starkweather skrev:and you can get a dchar with std.utf.toUTF32(). ReganStill working on a VB to D DLL interface. I want to pass a string to a D function. The only way I have been able to do it without errors is ByRef on the VB end, as expected, to a char* on the D end. However, I want to use the 'find' function on the string. 'find' requires a char[] and a dchar as inputs. I I haven't been able to figure out how to de-reference the pointer for the char[] and I don't know how to produce a dchar.a char* cStr is converted to char[] by cStr[0..std.c.string.strlen(cStr)] or std.string.toString(cStr)
Mar 21 2006
On Tue, 21 Mar 2006 20:30:46 +1200, Regan Heath <regan netwin.co.nz> wrote:On Tue, 21 Mar 2006 09:00:15 +0100, Oskar Linde <oskar.lindeREM OVEgmail.com> wrote:Oops, I should read the whole post before replying. Any character literal will be accepted as a dchar, eg. void foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :) ReganRory Starkweather skrev:and you can get a dchar with std.utf.toUTF32().Still working on a VB to D DLL interface. I want to pass a string to a D function. The only way I have been able to do it without errors is ByRef on the VB end, as expected, to a char* on the D end. However, I want to use the 'find' function on the string. 'find' requires a char[] and a dchar as inputs. I I haven't been able to figure out how to de-reference the pointer for the char[] and I don't know how to produce a dchar.a char* cStr is converted to char[] by cStr[0..std.c.string.strlen(cStr)] or std.string.toString(cStr)
Mar 21 2006
void foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
Rory Starkweather wrote:Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ... } I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunnevoid foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
VB6 internally stores strings in UNICODE. When calling external functions VB6 uses stub to convert string to/from ANSI format. If you want to pass string from VB in Unicode use declaration like this: Declare Function findChar Lib "..." (ByVal t As LONG) As Long and call that function as: retValue = findChar(StrPtr("Some string")) this will pass pointer to UNICODE string to externall function findChar In article <dvp71g$hv1$1 digitaldaemon.com>, James Dunne says...Rory Starkweather wrote:Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ... } I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunnevoid foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
NoBoDy wrote:VB6 internally stores strings in UNICODE. When calling external functions VB6 uses stub to convert string to/from ANSI format. If you want to pass string from VB in Unicode use declaration like this: Declare Function findChar Lib "..." (ByVal t As LONG) As Long and call that function as: retValue = findChar(StrPtr("Some string")) this will pass pointer to UNICODE string to externall function findChar In article <dvp71g$hv1$1 digitaldaemon.com>, James Dunne says...Thanks! That helps a lot for me as well. So then am I still correct in that D should work with a wchar* ? BTW, do you have an MSDN reference for that info? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneRory Starkweather wrote:Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ... } I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunnevoid foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
"James Dunne" <james.jdunne gmail.com> wrote in message news:dvpa6h$ltk$1 digitaldaemon.com...NoBoDy wrote:VB strings are equivalent to COM's BSTR (which is wchar*), so you should be using SysAllocString and SysFreeString on the D side, just as you would with COM in C/C++. This article has some good pointers for interfacing VB with C++, which might help. http://www.flipcode.com/articles/article_vbdlls.shtmlVB6 internally stores strings in UNICODE. When calling external functions VB6 uses stub to convert string to/from ANSI format. If you want to pass string from VB in Unicode use declaration like this: Declare Function findChar Lib "..." (ByVal t As LONG) As Long and call that function as: retValue = findChar(StrPtr("Some string")) this will pass pointer to UNICODE string to externall function findChar In article <dvp71g$hv1$1 digitaldaemon.com>, James Dunne says...Thanks! That helps a lot for me as well. So then am I still correct in that D should work with a wchar* ? BTW, do you have an MSDN reference for that info? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneRory Starkweather wrote:Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ... } I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunnevoid foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
In article <dvp95v$krm$1 digitaldaemon.com>, NoBoDy says...VB6 internally stores strings in UNICODE. When calling external functions VB6 uses stub to convert string to/from ANSI format. If you want to pass string from VB in Unicode use declaration like this: Declare Function findChar Lib "..." (ByVal t As LONG) As Long and call that function as: retValue = findChar(StrPtr("Some string")) this will pass pointer to UNICODE string to externall function findCharNow that I hadn't seen before. If I can get it to work, it will solve a whole bunch of problems. Thanks. Rory
Mar 21 2006
How do I join this newsgroupd if that is what this is? What do I use for NNTP?
Mar 21 2006
Rory Starkweather wrote:How do I join this newsgroupd if that is what this is? What do I use for NNTP?You use a NNTP-client ;) Most modern email-readers have one. Windows-users seems to prefer Thunderbird, although Outlook Express work. It should be fairly easy process: Add an News-account (similar to email account) for the news.digitalmars.com server. Then you can search that server for groups, and you "subscribe" to those you're interested in. Posting and reading is then almost like reading/writing email.
Mar 21 2006
Thanks. It was as easy as you said.
Mar 21 2006
Correct me on this if I am wrong: UNICODE is *not* an _encoding_ standard; it is a standard mapping of character glyphs to integer values and specifies no requirements for storage or encoding. The encoding to which you (and many others) refer to by the name of UNICODE is in fact UCS-2, I believe. This is the encoding where the Basic Multilingual Plane (BMP) of the Unicode table maps directly onto 65536 values. NoBoDy wrote:VB6 internally stores strings in UNICODE. When calling external functions VB6 uses stub to convert string to/from ANSI format. If you want to pass string from VB in Unicode use declaration like this: Declare Function findChar Lib "..." (ByVal t As LONG) As Long and call that function as: retValue = findChar(StrPtr("Some string")) this will pass pointer to UNICODE string to externall function findChar In article <dvp71g$hv1$1 digitaldaemon.com>, James Dunne says...-- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneRory Starkweather wrote:Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ... } I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunnevoid foo(dchar c) {} void main() { foo('a'); } so you'll probably have no trouble there. :)Thanks for the help. I'm still not sure how to get VB to send a dchar, but there are only a couple of possibilities. Unless you are suggesting that I pass it to D as a string and then use a conversion function on it.
Mar 21 2006
James Dunne wrote:Correct me on this if I am wrong: UNICODE is *not* an _encoding_ standard; it is a standard mapping of character glyphs to integer values and specifies no requirements for storage or encoding.Well, since you asked - it's not glyphs, but characters :) http://en.wikipedia.org/wiki/GlyphThe encoding to which you (and many others) refer to by the name of UNICODE is in fact UCS-2, I believe. This is the encoding where the Basic Multilingual Plane (BMP) of the Unicode table maps directly onto 65536 values.And here it's more complicated. UCS-2 is exactly what you say, but AFAIK D uses UTF-16 and so does Windows: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_9i79.asp They're almost the same, except UTF-16 allows surrogate pairs for encoding other character planes, while UCS-2 doesn't. I think UCS-2 is somewhat deprecated generally, exactly because of this reason. xs0
Mar 21 2006
Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ...I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can.I may be running into that now. I decided to forget about the dchar issue and use another version of find: find (char[] s, char[] sub) I don't get any compile errors or nasty comments from VB, but the value I get back indicates that the character is not in the strin (-1) ************************** Here's the VB stuff Public Declare Function findACharInString _ Lib "E:\DigitalMars\Work\DInStr.dll" _ (ByRef strString As String, _ ByRef strSearchChar As String) _ As Long Private Sub cmdTest1_Click() Dim lngCharPointer As Long Dim strString As String Dim strChar As String * 1 strString = "Fred" strChar = "e" lngCharPointer = findACharInString(strString, strChar) MsgBox strChar & " found at " & CStr(lngCharPointer) End Sub ******************************* Here's the D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } } I figured that the string and the character might not look the same after they were massaged, so I added this: void main(char[][] Args) { int iRetVal; iRetVal = findACharInString(Args[1], Args[2]); printf("%s found at %d\n", Args[2], iRetVal); } That just causes more problems. When I try to run it I get an Access Violation. (?) I can't find that note on the caveat for printf and strings, so I assume I'm running into that problem here. I originally tried using writefln in findACharInString and consistently got "Unknown software exception (0xe0440001) occurred in app at location 0x7c59bc3f. (I was surprised that it was so consistent.) So I must not understand that function either. I think the way I tried to do it looked like this: writefln("The string: %s", theString); writefln("The character: %s", theChar); Its amazing that so many things can go wrong with a program that is only 7 lines long. Part of the problem is that it has been 10 years since I have used C, and I have never used D before this week. There seems to be a hump in learning "new" programming languages. One day nothing works the first ten times and the next day about half of what you write works the first time. I'm not at that point yet. Rory Aggressively seeking arcane knowledge.
Mar 21 2006
Rory Starkweather wrote:I think we've discovered in another reply thread that the source of the error is the use of char* instead of wchar* and the missing StrPtr() call on the VB side. Learn something new every day!Actually you want to use wchar* at the D end from VB. VB sends 'Unicode' strings where each character is represented by two bytes. This is the equivalent of a wchar* in D. char, wchar, and dchar in D are all more-or-less interchangeable. The best way to get VB and D to do string work together is this: Declare Function findChar Lib "..." (ByVal t As String) As Long export extern (Windows) int findChar(wchar* str) { ...I'm not 100% sure if this works as I've had serious issues with VB6's string handling in the past (especially in scenarios like this). I think the trick is to initialize the string from VB's side and pass it in to C/C++/D for them to modify it. I'll do some more research on this and get you a better answer if I can.I may be running into that now. I decided to forget about the dchar issue and use another version of find: find (char[] s, char[] sub) I don't get any compile errors or nasty comments from VB, but the value I get back indicates that the character is not in the strin (-1) ************************** Here's the VB stuff Public Declare Function findACharInString _ Lib "E:\DigitalMars\Work\DInStr.dll" _ (ByRef strString As String, _ ByRef strSearchChar As String) _ As Long Private Sub cmdTest1_Click() Dim lngCharPointer As Long Dim strString As String Dim strChar As String * 1 strString = "Fred" strChar = "e" lngCharPointer = findACharInString(strString, strChar) MsgBox strChar & " found at " & CStr(lngCharPointer) End Sub ******************************* Here's the D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } }I figured that the string and the character might not look the same after they were massaged, so I added this: void main(char[][] Args) { int iRetVal; iRetVal = findACharInString(Args[1], Args[2]); printf("%s found at %d\n", Args[2], iRetVal); }Well, the error here (I would assume) is your use of %s instead of %.*s, yes arcane printf knowledge to the rescue again.That just causes more problems. When I try to run it I get an Access Violation. (?) I can't find that note on the caveat for printf and strings, so I assume I'm running into that problem here. I originally tried using writefln in findACharInString and consistently got "Unknown software exception (0xe0440001) occurred in app at location 0x7c59bc3f. (I was surprised that it was so consistent.) So I must not understand that function either. I think the way I tried to do it looked like this: writefln("The string: %s", theString); writefln("The character: %s", theChar);Wondering why this didn't work...Its amazing that so many things can go wrong with a program that is only 7 lines long. Part of the problem is that it has been 10 years since I have used C, and I have never used D before this week. There seems to be a hump in learning "new" programming languages. One day nothing works the first ten times and the next day about half of what you write works the first time. I'm not at that point yet. Rory Aggressively seeking arcane knowledge.It's the best kinda knowledge out there! Try looking up Sound Blaster 16 and VGA interrupts and output ports - that's some fun arcane knowledge. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunne
Mar 21 2006
I think we've discovered in another reply thread that the source of the error is the use of char* instead of wchar* and the missing StrPtr() call on the VB side. Learn something new every day!StrPtr() call? You're just saying that its unfortunate that VB doesn't have any civilized programming constructs aren't you? I have to admit that I have learned about three VB functions I had never heard of during the last few weeks. VB Help is of limited usefulness in finding things like that, unless I am also doing that incorrectly. I did make the change to wchar*. I'll try that too.I have made the change. I'll try it in a few minutes.Well, the error here (I would assume) is your use of %s instead of %.*s, yes arcane printf knowledge to the rescue again.I probably fat-fingered something.writefln("The string: %s", theString); writefln("The character: %s", theChar);Wondering why this didn't work...
Mar 21 2006
I'm totally lost now. The DLL version didn't like the wchar* types and it wouldn't compile. So I tried the command line version. It not only compiled, it worked perfectly. (Except for tht nasty and long forgotten 0 based things.) So I copied the command line version over the DLL version and I get: e:\DigitalMars\DMD\Bin\..\..\dm\bin\link.exe dinstr,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved OPTLINK : Warning 23: No Stack dinstr.obj(dinstr) Error 42: Symbol Undefined __nullext dinstr.obj(dinstr) Error 42: Symbol Undefined __ModuleInfo_3std6string OPTLINK : Warning 134: No Start Address --- errorlevel 2 I can't see a difference between what is in DInStr.d now and the code below that was posted before any changes. The new version is posted below the >> version, which is from an earlier message at a time when it compiled OK, but didn't work.******************************* Here's the ** NEW *** D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } } As I said, I can't see the difference. To confuse the issue even further, here's the commandline version, that works perfectly. I realize that I am passing char[] to findACharInString in this version but I don't see why it compiles without a hitch. Command line used: DInstrCL Fred e //--------DInStrCL.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } } void main(char[][] Args) { int iRetVal; iRetVal = findACharInString(Args[1], Args[2]); printf("%.*s found at %d\n", Args[2], iRetVal); }******************************* Here's the ** OLD *** D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } }
Mar 21 2006
Rory Starkweather wrote:I'm totally lost now. The DLL version didn't like the wchar* types and it wouldn't compile. So I tried the command line version. It not only compiled, it worked perfectly. (Except for tht nasty and long forgotten 0 based things.) So I copied the command line version over the DLL version and I get: e:\DigitalMars\DMD\Bin\..\..\dm\bin\link.exe dinstr,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved OPTLINK : Warning 23: No Stack dinstr.obj(dinstr) Error 42: Symbol Undefined __nullext dinstr.obj(dinstr) Error 42: Symbol Undefined __ModuleInfo_3std6string OPTLINK : Warning 134: No Start Address --- errorlevel 2 I can't see a difference between what is in DInStr.d now and the code below that was posted before any changes. The new version is posted below the >> version, which is from an earlier message at a time when it compiled OK, but didn't work.As much as I'd love to help you out, I'm also hopelessly lost. Can you ZIP up your project and document your test cases and post them on the NG or e-mail them to me personally? The e-mail I post with on the newsgroups is my valid e-mail. -- Regards, James Dunne******************************* Here's the ** NEW *** D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } } As I said, I can't see the difference. To confuse the issue even further, here's the commandline version, that works perfectly. I realize that I am passing char[] to findACharInString in this version but I don't see why it compiles without a hitch. Command line used: DInstrCL Fred e //--------DInStrCL.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } } void main(char[][] Args) { int iRetVal; iRetVal = findACharInString(Args[1], Args[2]); printf("%.*s found at %d\n", Args[2], iRetVal); }******************************* Here's the ** OLD *** D code: //--------DInStr.d----------- import DLLMain; import std.string; // For find extern (Windows) { int findACharInString(char* searchString, char* searchChar) { int iPointer = 0; char[] theChar; char[] theString; theString = std.string.toString(searchString); theChar = std.string.toString(searchChar); iPointer = find(theString, theChar); return (iPointer); } }
Mar 21 2006
James Dunne wrote:Rory Starkweather wrote:The working code is attached with a sample Excel spreadsheet with embedded VBA test code. Since VB uses equivalents of D's wchar* strings, you cannot easily use D's phobos string handling functions, since most of them expect char[] arguments, not wchar[]. My conclusion is that we really need wchar[] and dchar[] string-handling functions in phobos, or at least be assured that all the string-handling functions which accept char[] arguments assume UTF-8 encoding, not just ASCII. I had to look at the std.string.d module's find() method to see if it is accepting ASCII or UTF-8, and I couldn't figure out which! The code is: int find(char[] s, dchar c) { char* p; if (c <= 0x7F) { // Plain old ASCII p = cast(char*)memchr(s, c, s.length); if (p) return p - cast(char *)s; else return -1; } // c is a universal character foreach (int i, dchar c2; s) { if (c == c2) return i; } return -1; } This doesn't make a lick of sense to me why one can iterate over a char[] with foreach, expecting dchars to come out of it outside the range of ASCII... is there something going on under the hood that I'm not aware of? Is this code trying to imply that the char[] is being treated as UTF-8 magically? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunne...As much as I'd love to help you out, I'm also hopelessly lost. Can you ZIP up your project and document your test cases and post them on the NG or e-mail them to me personally? The e-mail I post with on the newsgroups is my valid e-mail.
Mar 22 2006
On Thu, 23 Mar 2006 02:59:09 +1100, James Dunne <james.jdunne gmail.com> wrote:I had to look at the std.string.d module's find() method to see if it is accepting ASCII or UTF-8, and I couldn't figure out which! The code is: int find(char[] s, dchar c) { char* p; if (c <= 0x7F) { // Plain old ASCII p = cast(char*)memchr(s, c, s.length); if (p) return p - cast(char *)s; else return -1; } // c is a universal character foreach (int i, dchar c2; s) { if (c == c2) return i; } return -1; } This doesn't make a lick of sense to me why one can iterate over a char[] with foreach, expecting dchars to come out of it outside the range of ASCII... is there something going on under the hood that I'm not aware of?The foreach() has a mode of operation that automatically converts UTF encodings one character at a time. Thus foreach(dchar c; "abcdef"c) is valid code.Is this code trying to imply that the char[] is being treated as UTF-8 magically?char[] *is* utf-8 it is not ASCII. No magic here. -- Derek Parnell Melbourne, Australia
Mar 23 2006
Derek Parnell wrote:On Thu, 23 Mar 2006 02:59:09 +1100, James Dunne <james.jdunne gmail.com> wrote:Okay, that's where I was confused. Thanks!I had to look at the std.string.d module's find() method to see if it is accepting ASCII or UTF-8, and I couldn't figure out which! The code is: int find(char[] s, dchar c) { char* p; if (c <= 0x7F) { // Plain old ASCII p = cast(char*)memchr(s, c, s.length); if (p) return p - cast(char *)s; else return -1; } // c is a universal character foreach (int i, dchar c2; s) { if (c == c2) return i; } return -1; } This doesn't make a lick of sense to me why one can iterate over a char[] with foreach, expecting dchars to come out of it outside the range of ASCII... is there something going on under the hood that I'm not aware of?The foreach() has a mode of operation that automatically converts UTF encodings one character at a time. Thus foreach(dchar c; "abcdef"c) is valid code.I understand that, I just didn't know the hidden foreach magic. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneIs this code trying to imply that the char[] is being treated as UTF-8 magically?char[] *is* utf-8 it is not ASCII. No magic here.
Mar 23 2006
I guess I would like to ask why I shouldn't do this at the same time I ask how to do it. I've been looking at a piece of code like: foreach (int i, dchar c; theString) { if (c == searchChar) return i + 1; } return 0; } I understand the reason for doing this, but prefer to do things like this: int iPointer; iPointer = 0; foreach (int i, dchar c; theString) { if (c == searchChar) iPointer = i + 1; // ?? break; } return (iPointer); } I realize that the extra integer takes up a little memory space, but . . . My questions are: Will 'break' work here? Why not do it this way?
Mar 23 2006
On Thu, 23 Mar 2006 17:51:09 -0600, Rory Starkweather wrote:I guess I would like to ask why I shouldn't do this at the same time I ask how to do it. I've been looking at a piece of code like: foreach (int i, dchar c; theString) { if (c == searchChar) return i + 1; } return 0; } I understand the reason for doing this, but prefer to do things like this: int iPointer; iPointer = 0; foreach (int i, dchar c; theString) { if (c == searchChar) iPointer = i + 1; // ?? break; } return (iPointer); } I realize that the extra integer takes up a little memory space, but . . . My questions are: Will 'break' work here?Yes it will, though it should be coded ... iPointer = 0; foreach (int i, dchar c; theString) { if (c == searchChar) { iPointer = i + 1; break; } } return (iPointer);Why not do it this way?It is just a coding-style issue. People code to different standards. BTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index into theString. This is significant if theString is not a dchar[]. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 24/03/2006 11:07:48 AM
Mar 23 2006
Derek Parnell wrote:BTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index into theString. This is significant if theString is not a dchar[].That is not correct. The index returned is an index into the char[] array, not the number of dchars processed: void main() { foreach(uint ix, dchar c; "åäö"c) writefln("c = %s, ix = %s",c,ix); } Prints: c = å, ix = 0 c = ä, ix = 2 c = ö, ix = 4 /Oskar
Mar 24 2006
Oskar Linde wrote:Derek Parnell wrote: =20 =20toBTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index in=ay,theString. This is significant if theString is not a dchar[].=20 =20 That is not correct. The index returned is an index into the char[] arr=not the number of dchars processed: =20 void main() { foreach(uint ix, dchar c; "=E5=E4=F6"c) writefln("c =3D %s, ix =3D %s",c,ix); } =20 Prints: =20 c =3D =E5, ix =3D 0 c =3D =E4, ix =3D 2 c =3D =F6, ix =3D 4 =20 /OskarI'm having some trouble understanding this implementation of the=20 'foreach' construct. From the definiton of the'foreach' expression, the=20 purpose of the 'c' in . . .; "=E5=E4=F6"c) is not clear to me. Does this = implicitly declare an array of items with the same data type as 'c'? In=20 other words, three dchars in this case? From Oskar's comment that seems=20 unlikely. For me a large part of the problem is the variable naming convention=20 in the documentation, which seems a little ambiguous, although reading=20 the entries carefully usually clarifies things. I think I am just not=20 used to one letter variable names yet. A style I have never been=20 comfortable with. Oddly enough, I am also trying to learn Oberon-2 now,=20 and Wirth uses the same convention.
Mar 24 2006
Rory Starkweather wrote:Oskar Linde wrote:No, the c is a suffix to the string literal, defining it as a char[]. Other suffixes are w and d for wchar[] and dchar[] respectively. Here follows a clearer version (with longer variable names ;) ): void main() { char[] string = "åäö"; // contains 6 UTF-8 code units foreach(uint index, dchar character; string) writefln("character = %s, index = %s",character,index); } In this case, the c suffix is superfluous since the data type of string (char[]) makes the conversion implicit. /OskarDerek Parnell wrote:I'm having some trouble understanding this implementation of the 'foreach' construct. From the definiton of the'foreach' expression, the purpose of the 'c' in . . .; "åäö"c) is not clear to me. Does this implicitly declare an array of items with the same data type as 'c'? In other words, three dchars in this case? From Oskar's comment that seems unlikely.BTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index into theString. This is significant if theString is not a dchar[].That is not correct. The index returned is an index into the char[] array, not the number of dchars processed: void main() { foreach(uint ix, dchar c; "åäö"c) writefln("c = %s, ix = %s",c,ix); } Prints: c = å, ix = 0 c = ä, ix = 2 c = ö, ix = 4 /Oskar
Mar 24 2006
follows a clearer version (with longer variable names ;) ):=20 void main() { char[] string =3D "=E5=E4=F6"; // contains 6 UTF-8 code units foreach(uint index, dchar character; string) writefln("character =3D %s, index =3D %s",character,ind=ex);} =20 In this case, the c suffix is superfluous since the data type of string==20(char[]) makes the conversion implicit. =20 /OskarSo this is like using & after a number in VB to say that it is type=20 Long? I thought that kind of thing was only used in languages that=20 didn't require variable type declarations. I can see how it would come=20 in handy though. Thanks.
Mar 24 2006
On Fri, 24 Mar 2006 19:05:30 +1100, Oskar Linde <olREM OVEnada.kth.se> wrote:Derek Parnell wrote:Thanks. It didn't used to be this way, I believe. -- Derek Parnell Melbourne, AustraliaBTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index into theString. This is significant if theString is not a dchar[].That is not correct. The index returned is an index into the char[] array, not the number of dchars processed: void main() { foreach(uint ix, dchar c; "åäö"c) writefln("c = %s, ix = %s",c,ix); } Prints: c = å, ix = 0 c = ä, ix = 2 c = ö, ix = 4 /Oskar
Mar 24 2006
Derek Parnell wrote:On Thu, 23 Mar 2006 17:51:09 -0600, Rory Starkweather wrote:Understood. The // ?? was added for emphasis.I guess I would like to ask why I shouldn't do this at the same time I ask how to do it. I've been looking at a piece of code like: foreach (int i, dchar c; theString) { if (c == searchChar) return i + 1; } return 0; } I understand the reason for doing this, but prefer to do things like this: int iPointer; iPointer = 0; foreach (int i, dchar c; theString) { if (c == searchChar) iPointer = i + 1; // ?? break; } return (iPointer); } I realize that the extra integer takes up a little memory space, but . . . My questions are: Will 'break' work here?Yes it will, though it should be coded ...iPointer = 0; foreach (int i, dchar c; theString) { if (c == searchChar) { iPointer = i + 1; break; } } return (iPointer);Good point. Thanks for mentioning it.I hadn't really considered that. Another option that has been suggested is using 'ifind' after suitable conversions. 'ifind' is pretty much guaranteed to give me a pointer to the actual character I want, isn't it?Why not do it this way?It is just a coding-style issue. People code to different standards. BTW, using the foreach this way can be misleading. The pointer value returned represents the number of dchars examined and *not* an index into theString. This is significant if theString is not a dchar[].
Mar 24 2006
Rory, I've put together some code that I got to work, you can download it in the following zip file: http://spottedtiger.tripod.com/Downloads/SampleDLL.zip David L. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!" ------------------------------------------------------------------- MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
Mar 21 2006
In article <dvqi0d$29mi$1 digitaldaemon.com>, David L. Davis says...Rory, I've put together some code that I got to work, you can download it in the following zip file: http://spottedtiger.tripod.com/Downloads/SampleDLL.zip David L. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!" ------------------------------------------------------------------- MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.htmlThanks. I was going to ask for this. Tom J
Mar 22 2006