Jump to content
Dave Nottage

Compiling code originally for VS in C++Builder

Recommended Posts

Posted (edited)

My Google-fu seems to be off at the moment.

 

I have a DLL project that was originally for Visual Studio that I'm attempting to port to C++Builder. I'm struggling to find any tips on making this migration, other than apparently some time ago C++Builder had a method of importing Visual C++ projects. Does any method exist for importing such a project, or perhaps a site that gives tips about it?

 

I've created a C-based DLL project in C++Builder and am attempting to include the original VS (C-based) code, however I'm receiving a bunch of compiler errors, which are different each time I load the project and hit "Build".

 

The motivation for moving it from VS is to have the ability to include Delphi code in the project.

 

Additional issue: I have a .lib file that is used in the VS project, but no corresponding .dll, so that I can use implib to import a .lib that C++Builder will link to. Is there a way I can create a .dll in VS so that everything in the .lib is imported?

Edited by Dave Nottage

Share this post


Link to post
Posted (edited)
22 hours ago, Dave Nottage said:

I've created a C-based DLL project in C++Builder and am attempting to include the original VS (C-based) code, however I'm receiving a bunch of compiler errors, which are different each time I load the project and hit "Build".

What kind of errors exactly?  Also, which version of C++Builder are you using?  Which of its many C++ compilers specifically are you using?  Are you using a compiler that is compatible with the C++ version that the VS code is targeting?

Quote

Additional issue: I have a .lib file that is used in the VS project, but no corresponding .dll

That would imply that the .lib file is probably a static library instead of an import lib for a DLL.

Quote

Is there a way I can create a .dll in VS so that everything in the .lib is imported?

If the VS project is for a static library rather than a DLL, then compiling it as a DLL may not be helpful since its code would likely not be setup to export symbols that IMPLIB could find.

Edited by Remy Lebeau

Share this post


Link to post
12 minutes ago, Remy Lebeau said:

What kind of errors exactly?

First one is: "[bcc32c Error] Api_HpcCallTable.h(181): pasting formed '->Hpc_Trace_AddClassId', an invalid preprocessing token" for this code:

int                HPC_CALL_TABLE_STUB(        Hpc_Trace_AddClassId,            (char* pszClassName), pszClassName);

Where HPC_CALL_TABLE_STUB is defined as:

#define HPC_CALL_TABLE_STUB( FuncName, ParamType, ...)			\
	__inline static FuncName##_Stub ParamType					\
{																\
	if(g_pHpcCallTable && NULL != g_pHpcCallTable->##FuncName)	\
	{															\
		return( (g_pHpcCallTable->##FuncName)(__VA_ARGS__));	\
	}															\
																\
	return( 0);													\
}

 

15 minutes ago, Remy Lebeau said:

Also, which version of C++Builder are you using?  Which of its many C++ compilers specifically are you using?  Are you using a compiler that is compatible with the C++ version that the VS code is targeting?

Great questions. I am using C++Builder 10.3.1 Community Edition. Am I able to choose a different compiler depending on the situation? If so, how? As advised, I created a DLL project and chose C as the language. I have extremely limited experience with C++Builder

 

17 minutes ago, Remy Lebeau said:

That would imply that the .lib file is probably a static library instead of an import lib for a DLL.

That seems logical to me. The issue here is that C++Builder will not link to the .lib file as-is, and I assume it's because it's in COFF format. I tried to use COFF2OMF to convert it, however that does not appear to produce a .lib that contains all the required code

Share this post


Link to post
Posted (edited)
4 hours ago, Dave Nottage said:

First one is: "[bcc32c Error] Api_HpcCallTable.h(181): pasting formed '->Hpc_Trace_AddClassId', an invalid preprocessing token"

bcc32c is the CLang-based Windows 32bit compiler.  What you are seeing is a CLang error message.  See Stricter C++ Compilers (Clang-enhanced C++ Compilers): Token Pasting in Embarcadero's documentation.

 

Also, I don't think __VA_ARGS__ will work in this situation, as that would pass FuncName as the first parameter to FuncName().  I'm sure Hpc_Trace_AddClassId() does not expect Hpc_Trace_AddClassId as its first parameter value.

Quote

Am I able to choose a different compiler depending on the situation? If so, how?

In the Project Options, in the C++ Compiler section, there is a "Use 'classic' Borland compiler" option.

Edited by Remy Lebeau

Share this post


Link to post
1 hour ago, Remy Lebeau said:

In the Project Options, in the C++ Compiler section, there is a "Use 'classic' Borland compiler" option.

OK, we're a step closer. The DLL compiles, however now I need to export a function contained in the .lib, namely: Load. I've created a .def from a VS C DLL that I know works:

LIBRARY     WSCTX.DLL

EXPORTS
    Load                           @1   ; Load

..and added it to the project, however I now receive this error:

[ilink32 Error] Invalid command line switch for "ilink32". Parameter "ItemSpec" cannot be null.

Either my Google-fu has once again disappeared, or I seem to be alone in ever receiving it using C++Builder?

Share this post


Link to post
14 hours ago, Dave Nottage said:

I've created a .def from a VS C DLL that I know works

I rarely use .DEF files in my C++Builder DLLs, I prefer to use 'extern "C"' and __declspec(dllexport) in the DLL's source code instead.  .DEF files are good when you need custom control over how exports are name-mangled and/or assigned ordinal values.  In most cases, that is not necessary.

14 hours ago, Dave Nottage said:

however I now receive this error:


[ilink32 Error] Invalid command line switch for "ilink32". Parameter "ItemSpec" cannot be null.

 

I have never seen that error before, and the only reference to it I find online is this:

 

https://stackoverflow.com/questions/5707046/

 

However, I have never upgraded my C++Builder to a version that is based on MSBuild, either.  I still use C++Builder 6.

Share this post


Link to post
1 hour ago, Remy Lebeau said:

I prefer to use 'extern "C"' and __declspec(dllexport) in the DLL's source code instead

The trick here is that the function that needs to be exported from the DLL is actually in the .lib. Is it possible to use extern "C"' and __declspec(dllexport) with it?

Share this post


Link to post
28 minutes ago, Dave Nottage said:

The trick here is that the function that needs to be exported from the DLL is actually in the .lib. Is it possible to use extern "C"' and __declspec(dllexport) with it?

Those modifiers can be applied directly to the function declaration.

 

But, are you referring to a VS static library that you want to link inside your C++Builder DLL?  Or are you referring to the import lib that the C++Builder compiler outputs in addition to the DLL?  I'm confused about your setup and what you are trying to accomplish exactly.

Share this post


Link to post
3 minutes ago, Remy Lebeau said:

Those modifiers can be applied directly to the function declaration.

 

But, are you referring to a VS static library that you want to link inside your C++Builder DLL?

Yes, so we'll give that a shot; thanks!

Share this post


Link to post

Having trouble with the declaration:

 

extern "C" __declspec(dllexport) int Load(pLink: PDLLLINK);

Gives: Declaration terminated incorrectly.

Share this post


Link to post
45 minutes ago, Dave Nottage said:

Having trouble with the declaration:

 


extern "C" __declspec(dllexport) int Load(pLink: PDLLLINK);

Gives: Declaration terminated incorrectly.

You appear to be mixing C/C++ and Delphi syntaxes.  It should be:

 

extern "C" __declspec(dllexport) int Load(PDLLLINK pLink);

Or:

extern "C" int __declspec(dllexport) Load(PDLLLINK pLink);

 

Share this post


Link to post
Posted (edited)
On 3/7/2019 at 11:21 AM, Remy Lebeau said:

extern "C" __declspec(dllexport) int Load(PDLLLINK pLink);

Or:


extern "C" int __declspec(dllexport) Load(PDLLLINK pLink);

Neither of those compile, giving the same error: Declaration terminated incorrectly.

 

It compiles OK omitting: extern "C", however the Load function is not exported, either. Could this be due to the .lib not being linked? I can name Load as Loadx instead, and the project still compiles.

 

I'm using ObjConv from here: https://agner.org/optimize/ to convert the original .lib file to OMF format. C++Builder does not complain about the file being linked, however I'm wondering whether it is sufficient for it to use.

 

Edited by Dave Nottage

Share this post


Link to post
18 hours ago, Dave Nottage said:

Neither of those compile, giving the same error: Declaration terminated incorrectly.

Works fine for me.

18 hours ago, Dave Nottage said:

It compiles OK omitting: extern "C", however the Load function is not exported, either.

The extern "C" has nothing to do with the exporting itself, that is handled by the __declspec.  The extern "C" simply disables name mangling on the exported name.

18 hours ago, Dave Nottage said:

I'm using ObjConv from here: https://agner.org/optimize/ to convert the original .lib file to OMF format. C++Builder does not complain about the file being linked, however I'm wondering whether it is sufficient for it to use.

I've never had to resort to that.  But then again, I've never tried linking to 3rd party static .lib files that are not already compatible with C++Builder, and import .lib files for DLLs are easy to regenerate using C++Builder's implib.exe.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×