undefined reference to static library

Started by alex-rudenkiy, November 02, 2019, 12:20:36 AM

Previous topic - Next topic

alex-rudenkiy

Please tell me why I don't have a static library, I've tried everything.  :sad: :sad: :sad:

Cpp file:

#pragma comment(lib,"C:\\masm32\\mySTATICdll.lib")
extern "C" __declspec(dllimport) void _stdcall sort_stdcall_static(void* a, int start, int b, void* res);

void main(){
    ...
    sort_stdcall_static(&src,1,5,dst);
    ...
}



mySTATICdll.asm:

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    ; -------------------------------------------
    ; Build this DLL with the provided MAKEIT.BAT
    ; -------------------------------------------

      .data?
        hInstance dd ?

      .code

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

LibMain proc instance:DWORD,reason:DWORD,unused:DWORD

    .if reason == DLL_PROCESS_ATTACH
      mrm hInstance, instance       ; copy local to global
      mov eax, TRUE                 ; return TRUE so DLL will start

    .elseif reason == DLL_PROCESS_DETACH

    .elseif reason == DLL_THREAD_ATTACH

    .elseif reason == DLL_THREAD_DETACH

    .endif

    ret

LibMain endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

sort proc a:dword, _start:dword, _end:dword, res:dword
        ...   
    ret
sort endp

sort_stdcall_static proc stdcall a:dword, _start:dword, _end:dword, res:dword
    invoke sort, a, _start, _end, res
    ret
sort_stdcall_static endp

end LibMain


mySTATICdll.def:
LIBRARY mySTATICdll
;EXPORTS sort_stdcall_static ;I've also tried this option.
EXPORTS _imp__sort_stdcall_static@16=sort_stdcall_static


Error:
CMakeFiles\untitled4.dir/objects.a(main.cpp.obj): In function `main':
D:/Users/lol/CLionProjects/untitled4/main.cpp:48: undefined reference to `_imp__sort_stdcall_static@16'

TimoVJL

#1
use correct undecorated function/symbol name:
.cpp
extern "C" __declspec(dllimport) void stdcall sort_stdcall_static(void* a, int start, int b, void* res);

.asm
sort_stdcall_static proc stdcall export a:dword, _start:dword, _end:dword, res:dword
EDIT:
.def for undecorated namesLIBRARY mySTATICdll.dll
EXPORTS sort_stdcall_static=_sort_stdcall_static@16
\masm32\bin\ml.exe -coff mySTATICdll.asm -FemySTATICdll.dll -link -dll -def:mySTATICdll.def
May the source be with you

hutch--

Just keep in mind that this forum is an assembler forum, in many C based forums assembler questions will yield insults and getting kicked out. Please keep this stuff out of here.

TimoVJL

Was that manifest directed specifically for me ?
An attitude problem ?
May the source be with you

alex-rudenkiy

Quote from: TimoVJL on November 02, 2019, 01:46:11 AM
use correct undecorated function/symbol name:
.cpp
extern "C" __declspec(dllimport) void stdcall sort_stdcall_static(void* a, int start, int b, void* res);
.asmsort_stdcall_static proc stdcall export a:dword, _start:dword, _end:dword, res:dword

it didn't help. At least I can't figure out why you took out the bottom line from stdcall. Even if you add a lower underline, it still doesn't work, of course, by adding the export that you recommended.

Maybe there are some peculiarities in the make file?

@echo off
if exist mySTATICdll.obj del mySTATICdll.obj
if exist mySTATICdll.dll del mySTATICdll.dll
\masm32\bin\ml /c /coff mySTATICdll.asm
\masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL /DEF:mySTATICdll.def mySTATICdll.obj
del mySTATICdll.obj
del mySTATICdll.exp
dir mySTATICdll.*
pause

alex-rudenkiy

I also have suspicions in terms of connecting the library in C++ itself because, for example, I write a non-existent path to the library to check it, and it just swears that undefined reference

Vortex

Hi alex-rudenkiy,

Let's try to make a simple MS VC example using a Dll built with Masm. First of all, what you are trying to do is to create a dynamic link library and not a static library. A dynamic library's code can be shared among different processes. A static library will add code to your final executable. The content of the static library is not shared like Dllls during run-time.

A simple Dll exporting two functions :
.386
.model flat, stdcall
option casemap :none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

.code

LibMain     PROC instance:DWORD,reason:DWORD,unused:DWORD

    mov     eax,1
    ret

LibMain     ENDP

sum         PROC x:DWORD,y:DWORD

     mov    eax,x
     add    eax,y
     ret

sum         ENDP


StdOut      PROC lpszText:DWORD

    LOCAL   hOutPut  :DWORD
    LOCAL   bWritten :DWORD
    LOCAL   sl       :DWORD

    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov     hOutPut, eax

    invoke  lstrlen,lpszText
    mov     sl,eax

    invoke  WriteFile,hOutPut,lpszText,\
            sl,ADDR bWritten,NULL

    mov     eax, bWritten
    ret

StdOut      ENDP


END         LibMain


The module definition file :
LIBRARY sample
EXPORTS

StdOut
sum


Notice that you don't need always to decorate the exported functions.

Building the Dll :
\masm32\bin\ml /c /coff Sample.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /DLL /DEF:Sample.def Sample.obj

\masm32\bin\dumpbin /EXPORTS Sample.lib > ImplibExports.txt
\masm32\bin\dumpbin /EXPORTS Sample.dll > DllExports.txt


You can read the text files to inspect the decoration of the exported functions.

Calling the two functions from a VC++ project :
#include <stdio.h>

extern "C" {
            void __stdcall StdOut(char *string);
            int __stdcall sum(int x,int y);
           }

int main()
{
int a=90;
int b=10;
int c=sum(a,b);

StdOut("90 + 10 = ");
printf("%d",c);

return 0;
}


The StdOut function above is for demonstration purpose. Naturally, printf provides much more functionality.

Building the executable :
cl /FaTest.asm Test.cpp sample.lib

The assembly listing shows that we declare two external symbols, our Dll functions :
.
.
EXTRN _StdOut@4:PROC
EXTRN _sum@8:PROC


I used Visual Studio 2010 Express to compile Test.cpp

TimoVJL

#7
i just missed to tell this: mySTATICdll.defLIBRARY mySTATICdll.dll
EXPORTS
_sort_stdcall_static@16
sort_stdcall_static=_sort_stdcall_static@16  ; only for undecorated name


EXPORTS

export is nonexistent/useless keyword EDIT: Thank's AW
Directives Reference

to avoid .def file for exports and also to have undecorated nameoption dotname
.drectve SEGMENT INFO
db '-export:_sort_stdcall_static@16 -export:sort_stdcall_static=_sort_stdcall_static@16'
.drectve ENDS

Using decorated name

jwasm/uasm/asmc have -zze for undecorated names with export

undecorated names with polink[code]option dotname
.drectve SEGMENT INFO
db '-export:sort_stdcall_static=_sort_stdcall_static@16'
.drectve ENDS

EDIT: finally create better import-lib with polib.exe or Vortex def2lib.exe with quoted export names

LIBRARY mySTATICdll.dll
EXPORTS
"_sort_stdcall_static@16"

May the source be with you

aw27

Quote from: TimoVJL on November 02, 2019, 07:54:12 PM
export is nonexistent/useless keyword

export exists, it is in MASM manual.   :thup:
Use export and don't bother with .def files  :thdn:.

alex-rudenkiy

Quote from: Vortex on November 02, 2019, 06:20:58 AM
Hi alex-rudenkiy,

Let's try to make a simple MS VC example using a Dll built with Masm. First of all, what you are trying to do is to create a dynamic link library and not a static library. A dynamic library's code can be shared among different processes. A static library will add code to your final executable. The content of the static library is not shared like Dllls during run-time.

A simple Dll exporting two functions :
.386
.model flat, stdcall
option casemap :none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

.code

LibMain     PROC instance:DWORD,reason:DWORD,unused:DWORD

    mov     eax,1
    ret

LibMain     ENDP

sum         PROC x:DWORD,y:DWORD

     mov    eax,x
     add    eax,y
     ret

sum         ENDP


StdOut      PROC lpszText:DWORD

    LOCAL   hOutPut  :DWORD
    LOCAL   bWritten :DWORD
    LOCAL   sl       :DWORD

    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov     hOutPut, eax

    invoke  lstrlen,lpszText
    mov     sl,eax

    invoke  WriteFile,hOutPut,lpszText,\
            sl,ADDR bWritten,NULL

    mov     eax, bWritten
    ret

StdOut      ENDP


END         LibMain


The module definition file :
LIBRARY sample
EXPORTS

StdOut
sum


Notice that you don't need always to decorate the exported functions.

Building the Dll :
\masm32\bin\ml /c /coff Sample.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /DLL /DEF:Sample.def Sample.obj

\masm32\bin\dumpbin /EXPORTS Sample.lib > ImplibExports.txt
\masm32\bin\dumpbin /EXPORTS Sample.dll > DllExports.txt


You can read the text files to inspect the decoration of the exported functions.

Calling the two functions from a VC++ project :
#include <stdio.h>

extern "C" {
            void __stdcall StdOut(char *string);
            int __stdcall sum(int x,int y);
           }

int main()
{
int a=90;
int b=10;
int c=sum(a,b);

StdOut("90 + 10 = ");
printf("%d",c);

return 0;
}


The StdOut function above is for demonstration purpose. Naturally, printf provides much more functionality.

Building the executable :
cl /FaTest.asm Test.cpp sample.lib

The assembly listing shows that we declare two external symbols, our Dll functions :
.
.
EXTRN _StdOut@4:PROC
EXTRN _sum@8:PROC


I used Visual Studio 2010 Express to compile Test.cpp

I got it all figured out. Thank you so much, buddy with a nickname @Vortex. Everything compiled, started to think, why everything is fine through visual studio, and through clion the same is not compiled, the method of complex inferences I came up with an algorithm to solve the problem of several points:


  • At first, it wouldn't hurt to add the following line "target_link_libraries(untitled7 C://masm32//sampledll.lib)" to the CMakeLists.txt file
  • Add dll to the folder with the program
  • Profit :greenclp: