2015-05-28 7 views
0

У меня есть функция в неуправляемой DLL Win32, которая принимает переменное количество аргументов и поэтому должна быть __cdecl, а не __stdcall или любое другое соглашение о вызове. На данный момент я прямо ссылаюсь на DLL (то есть я использую LoadLibrary и GetProcAddress, а не ссылку на файл DLL .lib).Код очистки CDecl в явной привязке DLL

я могу вызвать функцию только штраф, но так как это cdecl мне нужно добавить следующую встроенные инструкции по сборке после каждого вызова:

retVal = addVecs(v1, v2, v3, v4); 
__asm add esp, 64 ;Sizeof VECTOR struct is 16 bytes 
printf("The sum of all these vectors is:\n\tMagnitude: %f\n\tDirection (radians): %f\n\n", retVal.mag, retVal.dir); 

Если я не включаю в себя встроенный ассемблер, то программа вылетает после звоните в addVecs.

Есть ли какой-либо способ, который я могу написать либо EXE, либо DLL, чтобы не требовалась инструкция встроенной сборки? Например, printf также является функцией __cdecl, но мне не нужно писать встроенную сборку, чтобы обеспечить очистку стека после каждого вызова, который я ему делаю.

+2

При хранении указателя функции после вызова 'GetProcAddress', хранишь ли вы его в указателе, который включает '__cdecl'? – paddy

+0

Не __cdecl обычно является стандартным вызовом в Win32? (По крайней мере, для кода, скомпилированного с помощью MSVC, и даже если сам Win32 API его не использует) – immibis

+0

@immibis Вы можете указать соглашение о вызове по умолчанию в качестве параметра компилятора. Это не то, на что вы должны положиться. Особенно при загрузке DLL, вы всегда должны быть явными. – paddy

ответ

1

Необходимо убедиться, что соглашение о вызове addVecs верное. Оплатите, чтобы быть явным об этом, и не полагаться на настройки вашего компилятора по умолчанию.

typedef VECTOR (__cdecl *addVecs_ptr)(VECTOR, VECTOR, VECTOR, VECTOR); 

static addVecs_ptr addVecs = NULL; 

Если вы использовали ЬурейеЕ как это, делает бросок легко позже, когда вы загружаете адрес:

addVecs = (addVecs_ptr) GetProcAddress(hSomeDllHandle, "addVecs"); 
+0

Помогает много! Я привык набирать стандартный макрос CALLBACK * при использовании GetProcAddress, что я забыл, что это #define для __stdcall –