Хорошо зная точный размер компилятора массива xNetworkBuffers, можно просто оптимизировать его. Будучи любопытным, я попробовал. Ниже приведен код с небольшими изменениями, вывод asm и объяснение:
#include <stdint.h>
typedef struct abc {
char data[10];
}NetworkBufferDescriptor_t;
NetworkBufferDescriptor_t xNetworkBuffers[5];
int bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
if( ( offset >= (uint32_t)(sizeof( xNetworkBuffers )) ) || ( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
return 0;
return (int) (pxDesc - xNetworkBuffers) + 1;
}
и вывод asm:
bIsValidNetworkDescriptor:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #20
str r0, [fp, #-16]
ldr r3, [fp, #-16]
ldr r2, .L5
blockquote>sub r3, r3, r2 str r3, [fp, #-8] ldr r3, [fp, #-8] cmp r3, #49 bhi .L2
[ 118] В блочном цитируемом асм-коде вы можете видеть, что он сравнивается с 49, а не с 50 (что является фактическим размером xNetworkBuffers), поэтому я получил выводldr r1, [fp, #-8] ldr r3, .L5+4 umull r2, r3, r1, r3 lsr r2, r3, #3 mov r3, r2 lsl r3, r3, #2 add r3, r3, r2 lsl r3, r3, #1 sub r2, r1, r3 cmp r2, #0 beq .L3 .L2: mov r3, #0 b .L4 .L3: ldr r3, [fp, #-16] ldr r2, .L5 sub r3, r3, r2 asr r2, r3, #1 mov r3, r2 lsl r3, r3, #1 add r3, r3, r2 lsl r1, r3, #4 add r3, r3, r1 lsl r1, r3, #8 add r3, r3, r1 lsl r1, r3, #16 add r3, r3, r1 lsl r3, r3, #2 add r3, r3, r2 add r3, r3, #1 .L4: mov r0, r3 add sp, fp, #0 @ sp needed ldr fp, [sp], #4 bx lr .L6: .align 2 .L5:
offset >= (uint32_t)(sizeof( xNetworkBuffers ))
также равен
offset > (uint32_t)(sizeof( xNetworkBuffers ) - 1) )
и в этом случае компилятор может использовать BHI, дающий те же результаты
У меня тоже была небольшая борьба с этим вопросом. Я нашел решение, используя частичное определение класса c # и расширив datacontext, созданный дизайнером dbml. Это решение вполне похоже на ответ tvanfosson. Вам нужно создать частичный класс datacontext с конструктором по умолчанию, который получает ConnectionString из настроек, а в свойствах DC конструктора dbml установить соединение на None. Таким образом, строка подключения не будет скомпилирована в dll. Datacontext автоматически получит строку подключения из настроек строки подключения web.config. Я не проверял, работает ли это и с app.config, но я думаю, что он должен работать нормально.
Вот пример частичного класса DC:
namespace MyApplication {
/// <summary>
/// Summary description for MyDataContext
/// </summary>
///
public partial class MyDataContext
{
public MyDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
}
}
Чтобы обезопасить себя от чего-либо в автогенерируемом коде, переопределите информацию о подключении в методе OnCreated() контекста данных:
using System.Configuration;
namespace MyApplication
{
partial void OnCreated()
{
// attempt to use named connection string from the calling config file
var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
if (conn != null) Connection.ConnectionString = conn.ConnectionString;
}
}
Таким образом, дизайнер dbml может делать подключение по-своему (что не очень приятно вне веб-проекта), но вы получаете окончательный контроль над подключением при запуске приложения.