georgeob

Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host


Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

Mike Danes

It looks like it is possible using Alias keyword in VB. I don't have VB6 to test but seems to work fine in VBA:

This is the VB part:

Private Declare Function summer Lib "D:\Projects\Tests\Forums\geodb\debug\geob.dll" Alias "_summer@8" (ByVal num1 As Long, ByVal num2 As Long) As Long

Note the Alias keyword followed by _summer@8. _ and @8 are always added by the C/C++ compiler for functions that use stdcall calling convention. 8 is the size of arguments in bytes (2 * sizeof(long) in this case).

And this is the C++ part:

extern "C" long __declspec(dllexport) __stdcall summer(long a, long b)

{

long result;

result = a + b;

return result;

}

extern "C" is used to prevent the compiler from exporting the summer function used a C++ mangled name which is complicated and may change from a compiler version to another.

What's wrong with using a DEF file

And don't think that you should have continued one of the other threads instead of creating another thread (I think it's the fourth) when the basic problem is the same





Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

Yes, I apologise. I am new to this website. I didn't know it mattered so much. It seemed like either the activity had died down on the other threads, or I had perhaps prematurely indicated that a previous reply was an answer. I will check myself in the future.

In regard to the def file. Earlier in the process of learning how to make a dll, I got one working using a method that required a seperate file to be compiled along with every program that uses the dll, if I remember correctly. I can't remember what the method was called. If I dig deep enough in my notes I might be able to find it, but perhaps this is unnecessary. My boss said that he didn't want to have to do that every time, so I got the impression that he didn't want to have to deal with any files that weren't absolutely necessary. This is why I got the idea of not using the def file. Perhaps it was a bad idea.

In regard to the last recomendation, yes it worked well and thanks again for sharing your expertize with the other viewers and myself. I hope to be proficient at programming myself one day, and be able to help others as well. My text books on C++ do not have anything on dll's, but maybe if I save up my pennies I can buy a book that will help, so I won't have to ask too many questions.

Thanks again.

George






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

Mike Danes

"I didn't know it mattered so much" and "for sharing your expertize with the other viewers "

That's the problem with 4 threads... for me it was easier to respond because I knew more details from the other threads. For some random viewer it may be more difficult to understand. Anyway the sky isn't falling, I just made a suggestion .

"or I had perhaps prematurely indicated that a previous reply was an answer"

You can always unmark a post as an answer.

"I got one working using a method that required a seperate file to be compiled along with every program that uses the dll"

I have no idea what method this could be but using a def file is quite standard for exporting functions from dlls. It's true that __declspec(dllexport) is somewhat easier to do but then you need to know exactly what function names are generated. For example cdecl calling convention adds a _ in front of the function name, stdcall adds _ and @ followed by a number that is the total size of the arguments in bytes.

I can't say that not using a def file is a bad idea but I rarerly saw dlls that export functions with decorated names like you get from using __declspec(dllexport).

"My text books on C++ do not have anything on dll's"

Until you buy a book you can search the MSDN index for words like stdcall, cdecl, dllexport, def files.





Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

OK Mike, thanks






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

Private Declare Function GetPaperAbsorbency Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\geob\Debug\geob.dll" (ByVal Ftn&, FilePath$) As Integer
Private Declare Function Cov2Key Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\geob\Debug\geob.dll" (ByVal Coverage&, ByVal MultFunct&, ByVal Ftn&, ByVal EF&, FilePath$) As Long

Above are two declarations of dll functions that I added to the dll I was working on. The VB program cannot find the entry point for Cov2Key. Is there something wrong with my declarations I can provide more source code if needed






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

I got the vb program to call the dll functions but there is a runtime error in the c++ code that causes it to fail and generate a Unhandled exception in VB6.exe (NTDLL.DLL):0x0000005; Access Violation error.  Then it indicates a problem with the following line of code in the assembly language in the disassembler:

cmp dword ptr[edx + 14h], 0

 

the code is as follows:

 

#include "stdafx.h"
#include "stdio.h"
int __stdcall GetPaperAbsorbency(int Ftn, char FilePath$)
{
 int MultFilNum;
 char PA$;
// char filename;
 //need C++ version of free file statement here

// filename = FilePath$;
// strcat(filename, ".MLT");

 FILE *fp;

 //need above line

 fp = fopen(&FilePath$, "r+");
 fread(&PA$, sizeof(char), 1, fp);
 fclose(fp);
 return (int)PA$;
}

long __stdcall Cov2Key(long Coverage, int MultFunct, int Ftn, int EF, char FilePath$)
{
 int KeyV;
 int PAbs;
 PAbs = GetPaperAbsorbency(Ftn, FilePath$);
 KeyV = ((Coverage*MultFunct/100000^(EF))*PAbs+0.5);
 return KeyV;
}

 

 






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

Mike Danes

Mmm... you have some problems here, you would really use to read a C/C++ book probably. C/C++ is quite different from VB.

1) char FilePath$

$ does not have any special meaning in C++, it's treated like any other character in an identifier. The result of this is that FilePath$ is a variable of type char and not a string. You need to use a pointer to char here:

char *FilePath

2) the commented out code (with strcat) now looks like this

char filename[256];

strcpy(filename, FilePath); //copy FilePath into filename

strcat(filename, ".MLT"); // append .MLT to filename

3) the file code, I'm not sure about this one, it really depends on what the file contains. I see that you only read on character from the file so I suppose this would work:

char PA;

fp = fopen(filename, "r+");
fread(&PA, sizeof(char), 1, fp);
fclose(fp);
return (int)PA;

4) Cov2Key

long __stdcall Cov2Key(long Coverage, int MultFunct, int Ftn, int EF, char *FilePath)
{
int KeyV;
int PAbs;
PAbs = GetPaperAbsorbency(Ftn, FilePath);
KeyV = ((Coverage*MultFunct/100000^(EF))*PAbs+0.5);
return KeyV;
}

Overall it looks OK but the expression for KeyV has some problems:

- you add 0.5 which will result in some real number but the result of the expression (and function) is int. Do you really intend that

- 100000^(EF), what do you expect ^ operator to do If you expect it to be "raise to power" it is not. ^ in C++ is bitwise XOR. Use the pow function if you need raise to power: pow(100000, EF)

- as it is now (with ^) MultFunct is int, 100000^EF is int and the result of this is that / is integer division (like \ in VB). I doubt this is what you really need here.

With the above a revised function would look like:

double __stdcall Cov2Key(long Coverage, int MultFunct, int Ftn, int EF, char *FilePath)
{
double KeyV;
int PAbs;
PAbs = GetPaperAbsorbency(Ftn, FilePath);
KeyV = ((Coverage * MultFunct / pow(100000, EF)) * PAbs + 0.5);
return KeyV;
}






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

Mike, or anyone else that might know, this is what I compiled. Is this what you had in mind I'm still getiing an error. I've been trying to figure out what would cause it. I know it has to do with the fileopen statement. But the debugger doesn't seem to indicate exactly what the problem is. It goes to a line of assembly language code so I can step through it, but I haven't been able to learn anything from that. Do you thiink I need to look at the instruction set for the processor Maybe if I was more familiar with the debugger I would have better luck... I tried to install the help files, but they didn't install correctly. Maybe my boss will know when he comes in. If you have any more suggestions, I would welcome them. In the meantime I will keep trying to figure it out.

// d.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "stdio.h"
#include"math.h"
int __stdcall GetPaperAbsorbency(int Ftn, char FilePath)
{
int MultFilNum;
char PA;
FILE *fp;
char filename(256);
//need C++ version of free file statement here

// strcopy(filename, FilePath);
// strcat(filename, ".MLT");

//need above line

fp = fopen(&filename, "r+");
fread(&PA, sizeof(char), 1, fp);
// fread(&PA$, sizeof(char), 1, stdin);
fclose(fp);
return (int)PA;
}

long __stdcall Cov2Key(long Coverage, int MultFunct, int Ftn, int EF, char FilePath)
{
int KeyV;
int PAbs;
PAbs = GetPaperAbsorbency(Ftn, FilePath);
KeyV = ((Coverage*MultFunct/pow(100000,EF))*PAbs+0.5);
return KeyV;
}






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

Viorel.

Maybe instead of this:

. . .

char filename(256);

// strcopy(filename, FilePath);

// strcat(filename, ".MLT");

. . .

you actually need this:

. . .

char filename[256];

strcpy(filename, FilePath);

strcat(filename, ".MLT");

. . .

Also the FilePath parameters probably must be of const char * type instead of single char.

 

I hope this helps.

 





Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

I narrowed the code down to just an attempt to write the value of the variable being passed to the dll function to a file. It mangles it somehow. Is there a trick to passing strings to a dll file One viewer wrote that you can't call C++ dll files from a vb program. Could that be true




Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

The code for the function and the VB declaration are as follows:

extern "C" __declspec(dllexport) int __stdcall changefile(char *filename)
{
FILE *fp;
fp = fopen("geo", "w");
fprintf(fp, filename);
fclose(fp);

return 4;
}


Private Declare Function changefile Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\d\Debug\d.dll" (ByRef filename$) As Integer

Any thoughts






Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

Viorel.

georgeob wrote:

[...]

Is there a trick to passing strings to a dll file

[...]

Any thoughts

I think you should use ByVal declaration:

Private Declare Function changefile Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\d\Debug\d.dll" (ByVal filename as String) As Integer

I hope it works.

See also: http://support.microsoft.com/kb/187912





Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

Thanks Viorel, that works.




Re: Visual C++ General Is there a way to create a dll in C++ without a def file and have it work for a Visual Basic Host?

georgeob

My boss doesn't want to use pass ByVal, because it will take too long. We tried a section of code that he wrote, and I keep getting a "Bad calling convention error". Is it possible to do this

Private Declare Function myFunc Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\d\Debug\d.dll" (ByRef filName$)

void __stdcall myFunc(char filName[256])
{
char *fp;
char filName2[256];
char outChar;
int i;

fp = &filName[0];

for (i=0;i<255;i++)
{
filName2Idea=*fp;
*fp++;
}
fp = &filName[0];
for (i=0;i<24;i++)
{
outChar = *fp;
printf("\n %c",outChar);
*fp++;
}
}